Bei einem Timing-Angriff ("Timing Attack") handelt es sich um eine Form eines Seitenkanalangriffs auf eine bestimmte Implementierung in Hard- oder Software. Die Möglichkeit eines Timing-Angriffs kann selbst bei einfachsten Entwicklungen zu erheblichen Auswirkungen auf die Sicherheit eines Systems führen.
Was ist ein Timing-Angriff?
Bei einem Timing-Angriff werden statistische Verfahren genutzt, um Unterschiede in der Zeitdauer einer bestimmten Operation zu erfahren. Es wird also beispielsweise gemessen, wie lange ein Webserver braucht, um auf eine Loginanfrage zu reagieren. Sollten sich bei den Messungen bestimmte Muster feststellen lassen, so könnten aus diesen Informationen extrahiert werden, die eigentlich geheim gehalten werden sollten. Klingt recht kompliziert, lässt sich aber anhand eines einfachen Beispiels recht eindrucksvoll demonstrieren.
In meinem Github Repository habe ich unter anderem ein in PHP geschriebenes Loginsystem hinterlegt. Der eigentliche, serverseitige Login wird von der Datei "do-login.php" ausgeführt. Im folgenden Beispiel habe ich den Code zur Demonstration etwas modifiziert und auf das wesentliche reduziert:
<?php // Username & Password als Variable speichern $username = $_POST['username']; $password = $_POST['password']; // Datenbankabfrage des Usernamens $query = "SELECT * FROM users WHERE username='" . $_POST['username'] . "'"; $result = mysql_query($query); // Wenn der Username existiert, dann ... if (mysql_num_rows($result) == 1) { // Speicher den Datensatz des Users in $row $row = mysql_fetch_assoc($result); // Generiere einen Hash des Userpassworts $hash = password_hash($password); // Vergleiche Hash mit gespeichertem Hash if ( $hash == $row['password'] ) { echo "Authentication successfully."; } else { echo "Authentication failed."; } } // Es existiert kein User mit dem Usernamen else { echo "Authentication failed."; } ?>
Zum Login in eine Anwendung bzw. auf einer Webseite wird ein Code wie oberer nahezu als Standard eingesetzt. Schlecht ist er auf dem ersten Blick nicht:
- Es ist für den Benutzer nicht ersichtlich, ob ein Username existiert. Er bekommt auch bei einem nicht existenten Usernamen stets die Meldung "Authentication failed" zurück.
- Der Code ist aufgeräumt, auf das wesentliche reduziert. Der Hash wird erst berechnet, wenn der User auch tatsächlich existiert, was effizient ist.
- Die SQL Abfrage wurde einfach gehalten, um Fehler durch Komplexität zu vermeiden.
Bei genauerem Hinsehen hat der Code jedoch einige erhebliche Schwachstellen.
Schwachstellen
Wer sich etwas mit PHP auskennt, kann versuchen, die Probleme im Quellcode vor dem Weiterlesen des Textes zu identifizieren.