Wie letzte Woche angekündigt, geht es diese Woche um die Verhinderung
von SQL-Injection.
Um das Einschleusen von SQL-Code zu verhindern, müssen alle Eingaben
vor ihrer Verwendung in einer SQL-Abfrage geprüft und ggf. bereinigt
werden. Und zwar wirklich alle und nicht nur die, die ein Benutzer
offiziell ändern kann. Ein Angreifer kann auch z.B. im Formular
versteckte Felder oder Cookies manipulieren. Außerdem müssen die
Eingaben auf dem Server geprüft werden. Eine Prüfung auf dem
Client kann vom Angreifer manipuliert oder umgangen werden. Auch der
manchmal genannte Rat, die Länge von Eingabefeldern zu
beschränken, schützt nicht vor dem Einschleusen manipulierter
Daten. Ein Angreifer kann problemlos eine eigene, manipulierte Webseite
verwenden, bei POST-HTTP-Requests die URL manipulieren oder die Daten
direkt über Telnet an den Server senden. Daher darf nur den direkt auf
dem Server geprüften Daten vertraut werden.
Eingaben prüfen
Der einfachste Fall sind Parameter, die nur numerische Werte annehmen dürfen. Diese Eingaben können direkt in Werte des entsprechenden Wertebereichs umgewandelt werden. Im Beispiel aus der letzten Woche trifft dies auf die Spalte BenutzerNr zu: Alle Eingaben dafür können in ganzzahlige positive Werte umgewandelt werden.
Ähnlich ist es bei Eingaben, die nur bestimmte Werte annehmen dürfen. Dies sind z.B. Eingaben für Staaten, Monatsnamen oder Produktgruppen in Webshops. In derartigen Fällen kann die Eingabe mit einer Liste zulässiger Werte verglichen und eine unzulässige Eingabe verworfen werden. Im Beispiel aus der letzten Woche trifft dies auf den Wert für den Status zu. Da dort nur die Werte normal und admin zulässig sind können alle anderen Eingaben verworfen werden.
Schwieriger ist die Behandlung von Eingaben, die beliebige Werte annehmen können. Dies trifft z.B. auf alle Arten von Namen oder allgemein Suchwörter zu.
Für manche Eingaben, z.B. E-Mail-Adressen oder Telefonnummern, kann man die Menge zulässiger Zeichen exakt bestimmen und die Eingabe dann mithilfe von regulären Ausdrücken darauf prüfen. Alle Eingaben, die unzulässige Zeichen enthalten, werden verworfen. Diese Methode ist jedoch nur anwendbar, wenn keine potenziell gefährlichen Zeichen wie z.B. das Quote-Zeichen (') zulässiger Teil der Eingabe sind. Ihr Vorteil: Die Eingabe enthält nach der Filterung mit Sicherheit nur erwünschte Zeichen.
Es gibt Fälle, in denen eine Einschränkung nicht möglich ist oder potenziell gefährliche Zeichen zulässiger Bestandteil der Eingabe sind. In diesen Fällen muss die Menge der möglichen gefährlichen Zeichen festgelegt und diese dann gezielt ausgefiltert oder maskiert werden. Der Nachteil dieser Methode: Ein für Angreifer nützliches Zeichen könnte bei der Festlegung der auszufilternden Zeichen übersehen werden.
Im Beispiel der letzten Woche gehört das Feld BenutzerName zu
diesen Fällen: Ein O'Conner wäre wohl kaum begeistert, wenn sein
Name zu OConner verkürzt oder sogar zurückgewiesen würde.
Daher muss in diesem Fall das Zeichen "'" so maskiert werden, dass es als Bestandteil der
Zeichenkette und nicht des Befehls interpretiert wird. Dies geschieht meist
durch Voranstellen eines Backslash: (\'). Dabei sollte jedoch bedacht werden, dass eine Eingabe wie z.B.
O'Conner zu O\'Conner wird. Damit der Eintrag in
der Datenbank gefunden wird, muss er daher auch so gespeichert worden sein.
Einige für Webanwendungen verwendete Programmiersprachen stellen bereits Funktionen zum Maskieren bereit, ansonsten können derartige Funktionen aber auch sehr einfach selbst formuliert werden.
In PHP gibt es die Funktionen addslashes() und speziell für MySQL
mysql_real_escape_string() zum Maskieren bestimmter Zeichen wie
"'" und "\". Den gleichen
Effekt erzielt man durch Einschalten von magic_quotes_gpc in der
Konfigurationsdatei php.ini. Beides zusammen führt jedoch zu Problemen, da die betreffenden Zeichen doppelt maskiert werden. Daher müssen bei aktiviertem magic_quotes_gpc alle Variablen vor der Behandlung mit mysql_real_escape_string() mit stripslashes() von den bereits eingefügten Backslashes befreit werden.
In Perl gibt es die Funktion quote() aus dem DBI-Modul, die die für die jeweils verwendete Datenbank kritischen Zeichen maskiert. Für ASP gibt es keine fertige Lösung, eine entsprechende Funktion kann jedoch mithilfe von replace() implementiert werden.
Ein Problem aller Filtermethoden ist, dass die Filter unter Umständen durch andere Darstellungsformen für die zu filternden Zeichen (z.B. UTF, URL-Kodierung) umgangen werden können.
Eine weitere Möglichkeit, das Einschleusen von SQL-Code zu verhindern, ist die Verwendung von Stored Procedures. Diese und weitere Gegenmaßnahmen gegen SQL-Injection-Angriffe sind das Thema der nächsten Woche.
Wenn Sie Fragen oder Themenvorschläge haben, können Sie diese gerne an die angegebene E-Mail-Adresse senden oder als Kommentar an die Kolumne anfügen.
















Es gibt auch einen Scanner (Maui Security Scanner) der automatisiert nach Sicherheitslücken wie SQL-Injection, Cross Site Scripting und ähnliches sucht. Den Scanner kann man finden unter: http://www.elanize.com
Es gibt auch einen Scanner (Maui Security Scanner) der automatisiert nach Sicherheitslücken wie SQL-Injection, Cross Site Scripting und ähnliches sucht. Den Scanner kann man finden unter: http://www.elanize.com