© saicle/Shutterstock.com
Die zehn größten Sicherheitslücken im Web

Die Spitze des Eisbergs


Im dritten und letzten Artikel der Reihe widmen wir uns dem sicheren Hashing von Passwörtern und der Frage, wieso das neue Passwort-API von PHP 5.5 solch ein großer Schritt nach vorne ist. Zudem geht es um das Access-Level-Control, dem großen Thema der Cross-Site Request Forgeries und dem Einsatz von Drittanbietersoftware.

Dass Passwörter entsprechend gut gewählt werden sollten, um nicht einfach durch eine Dictionary-Attacke geknackt zu werden, hatten wir ja bereits im ersten Artikel dieser dreiteiligen Serie beschrieben. Essenziell wichtig ist aber auch die korrekte Verschlüsselung der Passwörter, die zwangsläufig irgendwo gespeichert werden müssen, um die User später nach einem Loginversuch zu authentifizieren.

Passwort-API

Glücklicherweise haben wir seit PHP 5.5 ein neues Passwort-API, das „from scratch“ sehr sichere Hashes zu unseren Passwörtern generiert, aber was war das Problem mit unseren alten Funktionen?

Zunächst einmal muss ein sicherer Algorithmus gefunden werden, und md5 zählt sicherlich nicht dazu, denn jeder mögliche zu generierende md5-Hash wurde inzwischen gebrute-forced und die Hash-Tabellen sind so bekannt, dass diese sogar mit Google gefunden werden. Ähnliche Hash-Tabellen gibt es auch für etwas komplexere Algorithmen und wird es auch immer mehr geben, da aufgrund der ganzen Cloud-Farmen oder auch immer größer werdenden Botnetze für relativ wenig Geld sehr große Rechenleistungen zur Verfügung stehen.

Auch entsprechende wilde Konstrukte von md5, die dann nochmal mit base64 enkodiert werden (das übrigens kein Hash- oder Verschlüsselungsalgorithmus ist und deswegen hier gar nichts zu suchen hat) helfen nicht und machen das Knacken der Passwörter ggf. sogar einfacher, da die Anzahl der Hash-Konflikte erhöht wird, wenn z. B. md5 mehrfach oder sogar auf einen verkürzten String angewendet wird.

Aber die Nutzung eines guten Algorithmus allein ist nicht ausreichend, denn die zu generierenden Hashes müssen einen zufälligen Salt erhalten, der eben genau die Benutzung von Standard-Hash-Tabellen unmöglich macht. So wird zu jedem zu hashenden String ein neuer Salt generiert, der an den String angehängt wird und somit bei jeder Validierung dort vorkommen muss. Um nun also mit solch einer Hash-Tabelle zu arbeiten, muss diese schon speziell mit diesem Salt erstellt worden sein. Da sie für jedes Passwort einen eigenen Salt generieren, müsste man also schon Unmengen solcher Tabellen erzeugen, was den Aufwand enorm erhöht, je nachdem wie lang der Algorithmus benötigt mit der aktuellen zur Verfügung stehenden CPU-Leistung sogar unmöglich macht.

Klingt eigentlich gar nicht so schwer, doch dieses Wissen muss man erst mal haben und es dann auch entsprechend anwenden. Somit ist das neue Passwort-API zwar nicht unbedingt technisch, aber von der Usability für Entwickler ein Meilenstein und wird hoffentlich die Menge an unsicher gehashten Passwörtern sehr schnell verringern. Das Generieren und Verifizieren solch eines Passworts funktioniert nun also mit folgenden Funktionen:

$hash = password_hash($password); if (password_verify($password, $hash)) { // Success!  } else { // Failed :(  }

Mehr ist nicht notwendig. Der erste Aufruf password_hash würde einen entsprechenden Hash generieren und der zweite Aufruf password_verify überprüft diesen gegen ein gegebenes Passwort.

Sie fragen sich nun evtl., wieso der generierte Hash von password_hash nicht einfach mit einem Equal-Operator mit dem gespeicherten Wert in der Datenbank verglichen wird? Wie erwähnt fügt das Passwort-API zu jedem String automatisch einen neuen Salt hinzu, somit wird jedes Mal ein neuer Hash erstellt und ein entsprechender Vergleich würde fehlschlagen. password_verify geht dagegen her und liest den Salt entsprechend aus, um dann den ursprünglich gehashten Wert vergleichen zu können.

Aktuell wird zur Verschlüsselung automatisch ­BCRYPT eingesetzt, was aktuell als sicher angesehen wird, aber auch hier wurde direkt für die Zukunft mitgedacht. Mit neuen Releases von PHP wird auch der Algorithmus bei Bedarf aktualisiert, dennoch werden alte Passwörter verifiziert werden können, da der genutzte Algorithmus im Hash erkennbar ist und somit nicht mit der Abwärtskompatibilität gebrochen wird, neue Passwörter aber dennoch von einem stärkeren Algorithmus profitieren.

Sofern Sie noch kein PHP 5.5 einsetzen, gibt es auch einen Backport [1], der bis auf PHP 5.3.7 zurückgeht und von Anthony Ferrara bereitgestellt wird.

Rainbow Tables

Neben inzwischen öffentlichen Hash-Tabellen, die jeden möglichen Hash enthalten, gibt es eine weitere Gefahr in Tabellenform, die als Rainbow Tables (Abb. 1) bezeichnet werden. Um eine Rainbow Table zu erstellen, benötigt man zwei Funktionen:

  • Eine Hash-Funktion; diese muss dieselbe sein, wie sie auch verwendet wurde, als der zu knackende Hash generiert wurde. Sie sehen schon, wenn Sie entsprechende Salts einsetzen, ist es ungleich schwerer, Ihre Hashes mit Rainbow Tables zu kna...

Neugierig geworden? Wir haben diese Angebote für dich:

Angebote für Teams

Für Firmen haben wir individuelle Teamlizenzen. Wir erstellen Ihnen gerne ein passendes Angebot.

Das Library-Modell:
IP-Zugang

Das Company-Modell:
Domain-Zugang