Zum Inhalt springen
Der Guide für ein smartes Leben.
SQL-Injection

Teil 2: SQL-Injection: So schützen Sie Ihre Webserver vor Hackerangriffen

Autoren: Redaktion pcmagazin und Anna Kobylinska • 8.3.2010 • ca. 2:10 Min

mysql_query($sql) or exit(mysql_error());...

mysql_query($sql) or exit(mysql_error());

Diese an sich gut gemeinte Fehlerabfangroutine hat den Nachteil, dass sie sich leicht ausmanövrieren lässt, wenn die Eingabe nicht gefiltert wird. Wird über ein Formularfeld ein einfaches Anführungszeichen abgeschickt, ergibt sich daraus:

$sql = "SELECT * FROM users WHERE
benutzername = ''' AND passwort = 'dfgr007pmm5qawsxysq98ghrtruzue5'";

Wird diese Abfrage an MySQL gesendet, so erscheint eine Fehlermeldung der folgenden Art: You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'WHERE benutzername = ''' AND passwort = 'dfgr007pmm5qaw.

Mit nur wenig Zusatzaufwand hat der Angreifer nun die Namen zweier Datenbankvariablen ermittelt: benutzername und passwort, außerdem auch die Reihenfolge, in der diese Variablen abgefragt werden. Zusätzlich weiß der Hacker auch, dass die Eingaben nicht korrekt gefiltert werden, denn es müsste einen Fehler der Applikation geben, der einen ungültigen Benutzernamen anmahnt.

Weiterhin müsste die Ausgabe ausmaskiert werden, sodass man nichts vom Datenbankfehler mitbekommen würde und schließlich dürfte der Einsatz der WHERE-Abfrage auch nicht sichtbar werden. Sobald ein Angreifer das Format der WHERE-Abfrage kennt, kann er versuchen, die Einträge zu manipulieren.

Von diesem Punkt aus hat der Angreifer viele Optionen, beispielsweise:

myuser' or 'foo' = 'foo' --

Damit wird die Abfrage schlicht zu:

$sql = "SELECT *
WHERE benutzername = 'myuser'
or 'foo' = 'foo' -- AND passwort =
'dfgr007pmm5qawsxysq98ghrtruzue5'";

Da -- einen SQL-Kommentar einleitet, wird die Abfrage an dieser Stelle effektiv ausgetrickst und auf diese Weise kann der Angreifer sich erfolgreich einloggen, obwohl er weder über einen gültigen Benutzernamen noch über ein gültiges Passwort verfügt.

MySQL-Hijacking

Sollte man zufälligerweise sogar über einen legitimen Benutzernamen verfügen, in unserem Beispiel peter, so ergibt sich:

peter' -

Wenn peter ein gültiger User ist, kann der Angreifer den Account übernehmen, weil sich die Abfrage wie folgt vereinfacht:

$sql = "SELECT * FROM users
WHERE benutzername = 'peter' --AND passwort = 'dfgr007pmm5qawsxysq98ghrtruzue5''";

Zum Abwehren von SQL-Injections muss jede Eingabe gefiltert (nicht ausmaskiert) und die Ausgabe ausmaskiert werden. Methoden zum Filtern der Eingabe wurden im Detail im Artikel "PHP Filter" besprochen. Begeht man den Fehler nur die Eingabe zu filtern, vergisst aber die Ausgabe auszumaskieren, werden sehr wahrscheinlich MySQL-Datenbankfehler auftreten.

Sicherheit
Diagnose der Verwundbarkeit einer Web-Applikation durch SQL-Injections mittels SQLfury.
© Archiv

Gültige Daten können hierbei unerwünscht mit dem Formular Ihrer SQL-Abfrage in Wechselwirkung treten. Dennoch ist es eher unwahrscheinlich, dass sich auf diese Weise das beabsichtigte Verhalten Ihres Formulars nennenswert verändert.

Auch den umgekehrten Fall, dass man die Ausgabe ausmaskiert und die Eingabe zu filtern vergisst, erschwert SQL-Injections erheblich. In dieser Konstellation wird ein erfolgreicher Angriff zwar nicht unmöglich, aber zumindest unwahrscheinlich.

Aufgrund einer nicht ausmaskierten Ausgabe kann aber unerwünschter Datenmüll entstehen und möglicherweise können sogar unangenehme Abstürze auftreten. Zum Ausmaskieren der Ausgabe genügt bei MySQL die Funktion mysql_real_escape_string():

$clean = array();
$mysql = array();
$clean['nachname'] = "Meier";
$mysql['nachname'] = mysql_real_
escape_string($clean['nachname']);
$sql = "INSERT INTO user (nachname)
VALUES ('{$mysql['nachname']}')";