SSL im Browser weiter absichern – Ist SSL alleine nicht sicher genug?

SSL steht für “Secure Sockets Layer” und ist eigentlich ein veralteter Begriff. Dennoch wird er weit häufiger verwendet und steht dadurch Synonym für seinen eigentlichen Nachfolger TLS (“Transport Layer Security“). Ob eine Browserverbindung per TLS gesichert ist erkennt man leicht am entsprechenden Icon in der Browserleiste, oder am “s” in “https://”. Leider blenden viele aktuelle Browser dieses Protokoll aus, so dass man sich nur noch auf die Icons verlassen kann. Im Screenshot sind 2 verschiedene Icons zu erkennen, da Facebook und die 1822direkt unterschiedliche Zertifikatstypen verwenden.

 

Zwei SSL-Zertifikate, wie man sie im Browser sieht

Zwei SSL-Zertifikate, wie man sie im Browser sieht

 

Facebook verwendet ein einfaches Zertifikat. Die Ausgabestelle bestätigt lediglich, dass das Zertifikat, mit dem Facebook seinen verschlüsselten Datenverkehr signiert, gültig ist. Ob es sich aber wirklich um Facebook handelt, ist bei diesem Zertifikat egal. Die 1822 hingegeben verwendet ein EV-Zertifikat (“Extended Validation”). Hierbei bestätigt die Ausgabestelle nicht nur die Gültigkeit des Zertifikats, sondern auch dass der Inhaber tatsächlich die 1822 ist. Den dafür notwendigen Anruf, die Unterschriften und das Sichten von Kopien amtlicher Dokumente lassen sich die Ausgabestellen dabei fürstlich entlohnen.

 

Ohne ein solches Zertifikat wäre es ein leichtes sich als Angreifer zwischen dem Server und dem Browser zu setzen und den Datenverkehr abzuhören. bei einem solchen “Man in the middle“-Angriff täuscht der Angreifer nämlich einfach beiden Seiten vor, selbst der Client bzw. der Server zu sein. Somit kann er selbst kontrollieren, welche Schlüssel verwendet werden, und den Datenverkehr selbst entschlüsseln. Zertifikate, die über vertrauenswürdige Stellen ausgegeben werden, erschweren diesen Angriff. Zwar kann der Angreifer dem Server immer noch vorgaukeln, selbst der Client zu sein. Aber den Client kann er nicht mehr täuschen, da Verschlüsselung und Zertifikat nicht mehr passen. Der Browser zeigt eine Warnung an und es liegt am Anwender, diese ernst zu nehmen (oder zu ignorieren).

 

Das schönste SSL-Zertifikat allerdings hilft nichts, wenn der Server die Verschlüsselung nicht erzwingt. Und selbst wenn der Server so konfiguriert wurde, dass er Anfragen automatisch auf einen verschlüsselten Datenstrom umleitet, ist dies nicht sofort per Definition sicher. Denn der Nutzer tippt im Browser doch nur “upjers.com” ein, ohne Protokoll. Der Browser erzeugt also eine Anfrage an “http://upjers.com”, ruft diese Seite unverschlüsselt auf und wird erst vom Server umgeleitet auf “https://upjers.com”. Während nun ein Angreifer, der zum Beispiel in einem offenen WLAN den Datenverkehr belauscht, durch die Umleitung keine Chance hat, die ins Login-Formular eingegebenen Nutzerdaten mitzulesen (Diese werden ja verschlüsselt übertragen), könnte er theoretisch bei diesem allerersten Aufruf von “http://upjers.com” ein Session-Cookie abfangen, das unverschlüsselt übertragen wird. Mit diesem Cookie könnte er durchaus die Chance haben, sich als gültigen Nutzer auszugeben und dem eigentlichen Inhaber des Cookies Schaden zufügen (Session verfügen über weitere Maßnahmen, die Gültigkeit des Cookies festzustellen, zumindest sollten sie das).

 

Wie also verhindert man, dass ein Cookie unverschlüsselt übertragen wird? Das ist eigentlich ziemlich einfach, denn Cookies verfügen über ein Flag, das den Browser anweist, Cookies nur über verschlüsselte Verbindungen zu übertragen. Dieses Flag nennt sich “secure”-Flag.

 

Set-Cookie: PHPSESSID=46fd11bd3c93e387a10b7e78f56dfc50; path=/; domain=.upjers.com; secure; HttpOnly

 

Dieses kleine Wörtchen “secure” sorgt dafür, dass der Browser das Cookie nur noch über verschlüsselte Datenströme überträgt (Natürlich macht das nur Sinn, wenn der Server ein solches Cookie ebenfalls nur über https setzt). “HttpOnly” heißt hier übrigens, dass das Cookie nicht per JavaScript ausgelesen und geändert werden darf.

 

Es gibt noch eine weitere Möglichkeit, den Datenverkehr zwischen Client und Server etwas sicherer zu machen. Man kann verhindern, dass überhaupt noch Anfragen an http:// gestellt werden, nachdem der Nutzer das erste Mal die Seite besucht hat. Es könnten ja nach wie vor http://-Links zur Seite existieren, die wiederum unverschlüsselt angefragt werden und ggf. Daten über den Nutzer preisgeben, die wir nicht in fremde Hände geben wollen. Es müsste also eine Möglichkeit geben den Browser zu zwingen, Links selbstständig auf https:// umzuschreiben. Und natürlich gibt es diese Möglichkeit. Auch das ist ein simples Flag, das diesmal im http-Response-Header übertragen wird. Es nennt sich Strict-Transport-Security.  Der Header-Eintrag erwartet einen Parameter “max-age”, der in Sekunden angibt, wie lange der Browser ab sofort jeden http-Link direkt per https aufrufen soll. Somit können auch Links von Drittseiten und Suchmaschinen einem potentiellen Angreifer nicht mehr verraten, zu welchen Themen sich der Nutzer gerade auf unserer informiert. Und die Gefahr, Daten unverschlüsselt zu übertragen, ist dadurch ebenfalls gebannt. Und so sieht es aus:

 

Strict-Transport-Security: max-age=47336400

 

Diese einfache Zeile im Response-Header sorgt dafür, dass der Browser die nächsten 1.5 Jahre alle Aufrufe unserer Seite nur noch per https gestatten wird. So einfach kann es sein mit zwei kleinen Korrekturen die Sicherheit von SSL / TLS deutlich zu erhöhen und zufälliges Ausspähen z.B. im Café nahezu unmöglich zu machen. Und für die meisten “normalen” Internetseiten lauert dort die größte Gefahr für den unbedarften Nutzer.

 

Hier noch ein vollständiger Header eines Aufrufs von https://upjers.com

HTTP/1.1 301 Moved Permanently
Date: Sun, 06 Apr 2014 11:32:36 GMT
Server: Apache/2.2.16 (Debian)
Strict-Transport-Security: max-age=47336400
P3P: CP=”invalid”
Set-Cookie: PHPSESSID=46fd11bd3c93e387a10b7e78f56dfc50; path=/; domain=.upjers.com; secure; HttpOnly
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
location: https://de.upjers.com/
Vary: Accept-Encoding
Content-Encoding: gzip
Content-Length: 20
Content-Type: text/html

Posted in Allgemein Meine Arbeit PHP by Marcus Schwarz. No Comments

Rekursiv Dateien anhand der Dateiendung kopieren…

… und dabei die Verzeichnisstruktur bewahren. Wie geht das eigentlich?

Neulich hatte ich das dringende Bedürfnis, aus einem schier unüberschaubaren Wust an Dateien in hunderten Unterverzeichnissen just jene herauszukopieren, die Quellcode-Dateien waren. Zuerst würde ich hier nun in Schleifen denken und zum Beispiel ein Bash-Script bauen, welches in einigen Zeilen Code die gewünschten Dateien sucht, die passenden Verzeichnisse anlegt, und danach die einzelnen Dateien kopiert. Aber, man ist ja gerne bequem, daher habe ich mich zuerst bei Almighty Google auf die Suche gemacht. Mit den richtigen Suchbegriffen findet man dort recht schnell sehr viele Lösungsansätze. Manche denken so kompliziert wie ich, andere sind schwer zu verstehen, dritte funktionieren schlicht nur in seltsamen Spezialfällen.

Die Perle, die ich gefunden habe, möchte ich hier für die Nachwelt festhalten. Sie ist an Einfachheit und Eleganz kaum zu überbieten, leicht zu merken und zu verstehen:

cd /zu/kopierendes/verzeichnis
find . -name '*.php' | cpio -pdm /pfad/zum/zielverzeichnis

Einfacher geht es nicht. Die Credits dafür gehen an “Iain” bei StackOverflow

Posted in Meine Arbeit PHP by Marcus Schwarz. 1 Comment

Best. Werbung. Ever.

Wenn es in diesem Jahr noch einen Post von mir gibt im Blog, dann diesen hier. Denn diese Werbung ist so überzeugend, man kann einfach nicht anders, als darauf zu klicken und das Produkt zu erwerben! Das dargestellte Testimonial ist an Seriosität nicht zu überbieten, und das Produkt ist so einfach zu nutzen, das geht auf keinen Fall zu toppen!

Also mich hat diese Werbung vollends überzeugt. Dich bestimmt doch auch?

Die beste Werbung aller Zeiten, oder?

Die beste Werbung aller Zeiten, oder?

Posted in Ein Kessel Buntes by Marcus Schwarz. No Comments

Mantis um eigene Status erweitern

Mantis ist ein beliebtes und verbreitetes Bugtracking-System. Während es “out-of-the-box” schon ziemlich mächtig ist und viele Funktionen bietet, lässt es sich mit einigen Tricks und Kniffen nochmal ordentlich aufbohren. Eine Einschränkung, die man auf diese Weise umgehen kann, ist der Ticket-Status. Während Mantis von Haus aus Status wie “neu“, “anerkannt” oder “erledigt” bietet, möchte man dies mitunter doch um eigene Status wie “bereit zum Testen” erweitern.
Leider gibt es dafür nicht nur eine zentrale Stelle, an der alles konfiguriert werden könnte, drum biete ich hier eine Schritt für Schritt-Anleitung anhand eines fiktiven Beispiels.

Wir möchten also nun eine neue Reihenfolge der Status eines Tickets einbauen. Diese sei “neu“, “Rückmeldung“, “zugewiesen“, “in Arbeit“, “bereit zum Testen“, “erledigt” und “geschlossen“.
Hierzu ergänzen wir zunächst die Datei “config_inc.php” um folgende Zeile:

$g_status_enum_string = '10:new,20:feedback,50:assigned,60:inprogress, 70:tobetested,80:resolved,90:closed';

Als nächsten ergänzen wir die Datei “custom_strings_inc.php“. Ist diese noch nicht vorhanden, legen wir sie an. Dort schreiben wir dann folgendes rein:

$s_status_enum_string = '10:neu,20:Rückmeldung,50:zugewiesen,60:in Arbeit,70:Bereit zum Testen,80:erledigt,90:geschlossen';

/* Der Status "inprogress" wurde in der Datei "config_inc.php" eingeführt! */
$s_inprogress_bug_button = "In Arbeit";
$s_inprogress_bug_title = "Setze Status auf In Arbeit";
$s_email_notification_title_for_status_bug_inprogress = "Dieses Ticket ist in Arbeit.";

/* Der Status "tobetested" wurde in der Datei "config_inc.php" eingeführt! */
$s_tobetested_bug_button = "Zu Testen";
$s_tobetested_bug_title = "Setze Status auf Zu Testen";
$s_email_notification_title_for_status_bug_tobetested = "Dieses Ticket ist bereit zum Testen.";

$s_my_view_title_tobetested = "Zu Testen";

Bietet man eine mehrsprachige Installation an, muss man in dieser Datei auch nach aktueller Sprache unterscheiden. Das sieht dann in etwa so aus:

if (lang_get_current() == 'german') {
    $s_tobetested_bug_button = "Zu Testen";
}
else {
    $s_tobetested_bug_button = "to be tested";
}

Zuletzt müssen wir im Verwaltungsmenü von Mantis noch eine Einstellung unter “Konfiguration verwalten” vornehmen. Hier ist der Eintrag “set_status_threshold” zu bearbeiten, und zwar müssen die Werte “30″ und “40″ entfernt werden. Warum? Ganz einfach, diese Einträge stehen für “acknowledged” und “confirmed“, beide haben wir aus dem System entfernt.

An dieser Stelle wären wir nun fertig. Doch was bringt es, einen neuen Status “zum Testen bereit” einzuführen, wenn ich nicht auf einen Blick sehen kann, welche Tickets zum Testen sind? Sorgen wir also noch dafür, dass alle Tickets mit dem Status “zum Testen bereit” im Dashboard (oder “Übersicht“) auftauchen.
Dazu müssen wir wieder ins Verwaltungsmenü unter “Konfiguration verwalten“. Hier tragen wir einen neuen Wert ein. Dieser hat den Namen “my_view_boxes” und den Typ “complex“. Natürlich soll er für alle Projekte und für alle Nutzer gleich sein. Folgenden Wert tragen wir dazu ein:

array (
    'assigned' => '1',
    'tobetested' => '2',
    'unassigned' => '3',
    'reported' => '4',
    'resolved' => '5',
    'recent_mod' => '6',
    'monitored' => '7',
)

Die Zahl in diesem Array gibt die Position des Abschnitts im Dashboard an. Ich habe “zum Testen bereit” soweit nach oben geschoben, dass die entsprechende Box garantiert gesehen wird. Eigentlich könnten wir an dieser Stelle fertig sein, doch leider ist Mantis hier ziemlich unkonsequent. Zwar kann man recht bequem neue Status einführen, und auf der “Übersicht“-Seite die Reihenfolge der System-Status ändern, doch welche Status angezeigt werden können ist hart kodiert. Wollen wir unseren “zum Testen bereit“-Status anzeigen, müssen wir also leider auch noch den Code von Mantis anfassen. Das ist aber gar nicht schwer.

Folgende Anpassungen müssen in der Datei “my_view_inc.php” gemacht werden. Scrollt man hier etwas nach unten findet man schnell das Array “$c_filter“, das mit allerlei Werten gefüttert wird. Wir suchen uns nun einfach den Eintrag von “$c_filter['resolved']“, und kopieren ihn schamlos, und geben die Kopie als unsere eigene aus, in dem wir sie statt dessen “$c_filter['tobetested']” nennen. Und weil es so schön war, machen wir das gleich noch mit “$url_link_parameters['resolved']“!

Nun haben wir unser Ziel fast erreicht. Innerhalb der von uns neu geschaffenen Zuweisung zu “$c_filter['tobetested']” findet sich folgende Zuweisung:

FILTER_PROPERTY_STATUS_ID => Array(
    '0' => $t_bug_resolved_status_threshold,
),

Daraus machen wir nun:

FILTER_PROPERTY_STATUS_ID => Array(
    '0' => 70, // Diese ID haben wir dem Status "tobetested" ganz am Anfang gegeben!
),

In “$url_link_parameters['tobetested']” machen wir aus der Variable “$t_bug_resolved_status_threshold” ebenfalls zweimal die “70″. Man könnte natürlich auch eine Variable “$t_bug_tobetested_status_threshold” in die “config_inc.php” schreiben, aber so kurz vorm Ziel drücken wir einfach mal beide Augen zu.

Und das war es auch schon. Unser Mantis Bugtracker wurde um zwei Status ergänzt und wir haben die “Übersicht”-Seite erweitert, um einen der neuen Status anzuzeigen. So schwer war es doch gar nicht!

Ich gebe zu, der Satz “um eigene Status erweitern” hört sich etwas holprig an. Mein Favorit für den Plural von Status wäre “Stati”. Doch der Duden lehrt: Der Plural von “der Status” heißt “die Status”. Und da man täglich ein bisschen was lernen sollte, war dies meine eigene Lektion für heute.

Tags: ,
Posted in Meine Arbeit PHP by Marcus Schwarz. 2 Comments

Alltagsgeschäft

Ich bin erschrocken über die Ignoranz oder Gleichgültigkeit vieler Menschen.

Auf dem Bürgersteig hält sich ein Mann an einem Laternenpfahl fest. Er sackt langsam, fast in Zeitlupe, zusammen und liegt ausgestreckt quer über dem Bürgersteig.

Ein Auto fährt vorbei, der Fahrer gafft. Ein zweites Auto fährt vorbei, der Fahrer gafft. Ein drittes Auto fährt vorbei, beinahe knallt der Fahrer gaffend in den noch immer gaffenden Vordermann. Ein Radfahrer donnert vorbei und flucht laut. Eine Frau mit Kinderwagen weicht über die Straße aus und schiebt ihr zweites Kind dabei noch weiter auf die Straße, weg von dem bösen Mann, der nun versucht, sich aufzusetzen, was ihm nicht gelingt. Aus der Tankstelle, vor der der Mann liegt, schaut man sensationsgierig aus dem Fenster.

Endlich bietet sich auf der vierspurigen Straße eine Gasse, ich überquere die Straße. Der Mann kann nicht aufstehen, brabbelt nur vor sich her, seine Wunden an den Beinen zeigen, dass er gerade nicht zum ersten Mal hingefallen ist. Ich weiß mir und ihm auch nicht zu helfen und rufe den Rettungsdienst. Quälend lange versuche ich den Mann dazu zu bewegen, einfach sitzen zu bleiben, statt ständig zu versuchen aufzustehen und wieder hinzufallen.

Weitere Passanten und Radfahrer laufen vorbei, tuscheln, schimpfen. Nach helfen ist keinem zumute, lieber hat man gute Ratschläge zur Hand. “Der soll halt nicht so viel saufen” [Alkohol konnte ich nicht riechen]. “Pass auf dass du dich nicht ansteckst” [Ich werd ihm schon nicht die blutenden Wunden ablecken]. “Platz da ihr Idioten, müsst ihr das unbedingt auf dem Radweg machen” [Ja!].

Wie sehr sich drei Minuten zur Ewigkeit dehnen können, wenn man eigentlich gar nicht weiß, was man machen soll. Immerhin weiß ich nun, gut drei Minuten dauert es in Bamberg, bis 2 Polizeistreifen, 1 Notzarzt und 1 RTW fast zeitgleich vor Ort sind, wenn jemand Hilfe braucht. Und das im Feierabendverkehr.

Und eigentlich möchte ich gar nicht über jene Schimpfen, die nicht helfen wollten oder konnten, sondern nur jenen Danke sagen, für die das Helfen ein solches Alltagsgeschäft ist, dass sie gar nicht mehr wahrnehmen, wie schwer es für Otto Normalhorst sein kann, genau das zu tun.

Danke.

Posted in Allgemein by Marcus Schwarz. No Comments