To main content

Reblog: PHP Session-Hash

Veröffentlicht von Benjamin Marwell am

Mein erster Blogeintrag (damals unter der Domain mampfit.wordpress.com) war das Thema Mahara und die Session-Hashes unter openSuse 11.1. Damals ärgerte ich mich sehr darüber, dass ein geänderter Standard in openSuses php.ini -Datei dazu führte, dass Mahara nicht funktionierte. Heute sehe ich das (teilweise) anders.

Warum Anwendungen flexibel sein müssen

Web-Anwendungen laufen heutzutage auf einer Vielzahl von Umgebungen. Vom typischen Linux bis zum (fast schon esoterischen) Windows, unter Apache httpd, wie auch unter nginx oder lighttpd. Alle Umgebungen unterscheiden sich ein bisschen. Meistens muss man auf diese gar keine Rücksicht nehmen, da man ja unter PHP entwickelt und viele Standards das Portieren vereinfachen. Dennoch kann es an unerwarteten Stellen zu Problemen kommen.

Die Konfiguration PHP Session-Hash

Eine dieser Spezialitäten ist die Einstellung, wie Session-Hashes generiert werden. Früher (so bis um 2009 herum) wurden die Hash-Werte (Erklärung) mittels des Algorithmus md5 erstellt. Das war völlig in Ordnung zur damaligen Zeit. Ab Mitte/Ende 2009 erkannte man aber Schwachstellen bei dem md5-Algorithmus - sogenannte Kollisionen. Man konnte Werte vorhersagen oder verschiedene Eingaben mit gleichem Hash erzeugen. Das war (und ist heute immer noch) ein großes Sicherheitsrisiko.

Glücklicherweise bot PHP seit Version 5.0 (also seit 2004!) die Möglichkeit, den Hash-Algorithmus umzustellen. Zunächst nur auf SHA1. Inzwischen sind aber auch durch die Hash-Erweiterung Algorithmen wie Whirlpool nutzbar. Diese Hashes sind wesentlich länger als z.B. noch md5, und brauchen daher ein größeres Datenbankfeld, so man diese in der Datenbank speichert.

Der Fehler liegt bei Mahara

Mahara kam also nicht damit klar, dass der Hash länger ist als erwartet. Die Erwartung von Mahara war aber von Anfang an falsch: Seit immerhin fünf Jahren hätte PHP ein Session-Hash zurückliefern können, was bei sha1 mit 160 Bit (Hex: 40 Bytes) länger ist als bei md5 mit 128 Bit (Hex: 32 Bytes). Und auch damals hat Speicher nicht die Welt gekostet, zumal Session-Hashes sowieso nur eine begrenzte Lebensdauer haben. Oft liegt diese im Bereich von einigen Stunden bis maximal wenigen Wochen.

Mahara war hier also eigensinnig und stur. Es hat die Entwicklung am Markt (hier: PHP) damals nicht ausreichend beobachtet und ist auf einen Anfängerfehler reingefallen.

Warum openSuse keine Schuld trifft

Damals hatte ich noch geschrieben, ich ärgere mich über openSuse, weil diese einen Default (md5) ändern. Diese Sicht teile ich heute nicht mehr. Grund ist, dass eine erhöhte Sicherheit -- auch damals schon -- immer gewisse Vorteile mit sich bringt. Bereits 2009 war der Rechenaufwand von sha1 gegenüber md5 ins Unbedeutende verschwunden. Es war also mehr als nur legitim, den Standard von md5 auf sha1 zu ändern.

Damals hatte ich noch geschrieben:

Sehr schön SuSE, danke für diese unnütze Hürde…

Heute würde ich wohl einfach einen Bug-Report bei Mahara einstellen, dass das Session-Feld zu klein ist.

Die Zeit: PHP-Session-Hashes heute

Leider ist md5 immer noch der Standard für die PHP-Session-Hashes -- zumindest gibt es traurigerweise keine Dokumentation, die das Gegenteil behauptet. Allerdings lässt sich die Konfiguration problemlos ändern, wie diese Antwort auf Stack Overflow zeigt:
Use a strong session hash identifier: session.hash_function in php.ini. If PHP < 5.3, set it to session.hash_function = 1 for SHA1. If PHP >= 5.3, set it to session.hash_function = sha256 or session.hash_function = sha512.

Unter anderem damit erhöht man die Sicherheit, da das Hijacken (also »Entführen«) einer Session damit drastisch erschwert wird. Dieses ist einer der vielen Werte, die man immer in seine php.ini -Datei eintragen sollte.