Giftspritze

Seite 3: Besser Coden

Inhaltsverzeichnis

Um SQL-Injection zu vermeiden, ist es notwendig, eingegebene Zeichenketten sorgfältig zu überprüfen und zu filtern, bevor die Applikation sie als Argument in einen SQL-Befehl expandiert und an die Datenbank sendet. Die Strategie des Filters sollte restriktiv sein. Dazu gibt es zwei Ansätze, die je nach Einsatzumgebung sinnvoll sind. Ist die zu erwartende Menge möglicher Benutzereingaben vorhersagbar, sollen nur diejenigen erlaubt sein, die in einer definierten Liste aufgeführt sind. Der Inhalt eines Feldes in das Anwender beispielsweise Automarken eingeben können, lässt sich mit einer Liste aller bekannten Marken vergleichen. Die Applikation verwirft die Eingabe, wenn sie keinem Eintrag in der Liste entspricht. Ähnlich den Filteransätzen bei Firewalls wäre dies eine "deny all, allow some"-Strategie.

Schwieriger wird das Filtern bei nicht vorhersagbaren Eingaben wie Straßennamen, Nachnamen und Telefonnummern. Hier funktioniert nur der "allow all, deny some"-Ansatz zufriedenstellend. Die Applikation darf nur Eingaben an die Datenbank weitergeben, die definierte Elemente nicht enthält: Das Quote-Zeichen und das Semikolon sind verboten. Auch die hintereinander gestellten Bindestriche ("--") dürfen nicht in der Zeichenkette zu finden sein. Andernfalls verwirft das Programm die Eingabe.

Zusätzlich sollte der Filter nach SQL-Befehlen in der Zeichenkette suchen. Trifft er dabei auf solch einen String, verwirft er ebenfalls die Anfrage. Allerdings ist dieses Vorgehen nicht immer pauschal richtig. Einige Content-Management-System speichern Texte in der Datenbank. Der vorliegende Text würde bei Berücksichtigung obiger Hinweise nie den Weg in solch ein System finden. Hier muss der Programmierer verschiedene Methoden kombinieren.

Sehr empfehlenswert ist der Einsatz von Prepared SQL-Statements beziehungsweise Stored Procedures. Dazu definiert man im Programm Templates der gewünschten SQL-Befehle und sendet sie an die Datenbank:

SELECT * FROM users WHERE card = ?

Diese speichert die Befehle und fügt später nur noch die zur Laufzeit übergebenen Parameter hinzu. Ein nachträgliches Einschleusen von zusätzlichen SQL-Befehlen ist dann nicht mehr möglich.

Schützenhilfe bei der Erstellung und dem Betrieb von Datenbank-Applikationen erhalten Programmierer von diversen Tools. Diese helfen schon in der Entwicklungsphase kritische Funktionen und Variablen zu erkennen und zu verbessern [8]. Spezielle Schwachstellen-Scanner überprüfen laufende Applikationen und verschiedene Datenbank-Produkte auf SQL-Injection, Cross-Site-Scripting und sogar Buffer Overflow und erstellen einen Bericht über gefundene Sicherheitslücken [7].

Normale Firewalls sind nicht in der Lage SQL-Injection abzuwehren, da ein Angreifer auf die Datenbank nur über ein Web-Frontend mit Formularen zugreift. Firewalls filtern auf Port-Ebene und der Zugriff auf das Frontend mit HTTP (Port 80) ist ja erlaubt.

Application-Level-Firewalls (Proxies), Firewalls mit Intrusion Prevention (IPS) und netzwerkbasierte Intrusion Detection Systeme (IDS) können zwar SQL-Fragmente in Paketen erkennen, daraus aber ein sinnvolles Regelwerk zu erstellen, ist sehr aufwendig, da das schützende System nichts über den aktuellen Kontext weiß. So darf ein spezieller Benutzer bestimmte Datensätze löschen, andere hingegen nicht. Das IDS kann dies aber nicht unterscheiden.

Spezielle Host-basierte Datenbank-Intrusion-Protection-Systeme (DB-IPS) [5,6] versuchen Angriffe auf die Datenbank zu erkennen und abzuwehren. Sie sind auch in der Lage zu unterscheiden, welche Applikation und welche Benutzer bestimmte Befehle an die Datenbank senden dürfen. Einige DB-IPS können sogar Anomalien in der Kommunikation feststellen, beispielsweise wenn eine Applikation plötzlich Kommandos übergibt, die zwar gültig sind, aber vorher noch nie aufgetaucht sind.

Eine vorherige Anmeldung am Server oder der Applikation beseitigt zwar nicht das SQL-Injection-Problem, grenzt doch aber die Zahl möglicher Benutzer ein. Ein Web-Server kann dann Schutz bieten, wenn die Verbindung mit SSL gesichert ist und die Authentifizierung in beide Richtungen erfolgt, also nicht nur der Server ein Zertifikat sendet, sondern auch der Client. Allerdings kann dann aufgrund der Verschlüsselung netzwerk-basierte Intrusion Prevention System nicht mehr in die Pakete hineinschauen; ein eventueller Angriff bliebe unerkannt. Für host-basierte IPS gilt diese Einschränkung nicht.

Eine Anmeldung über ein Webfrontend ist zwar denkbar, da aber meist auch die Anwender-Authentifizierung auf Datenbanken zurückgreift und somit für SQL-Injection anfällig ist, tritt der Fehler nur an anderer Stelle auf.

SQL-Injection wird zu einer ernst zu nehmenden Bedrohung für Web-Lösungen die Datenbanken verwenden. Inbesondere Applikationen die mit PHP und ASP entwickelt wurden, scheinen den Statistiken nach besonders anfällig zu sein. Die Zahl der Meldungen von Buffer Overflows in Open-Source-Lösungen und kommerziellen Produkten ist zwar weitaus größer, SQL-Injection-Attacken sind aber viel leichter durchzuführen, da ein Angreifer dazu nur einen Web-Browser benötigt. Programmierer müssen zukünftig sorgfältiger bei der Erstellung von Datenbank-Applikationen sein, um zu vermeiden, dass wichtige Daten kompromittiert werden.

[1] Advanced SQL-Injection

[2] More Advanced SQL-Injection

[3] Manipulating SQL-Server using SQL-Injection

[4] Verteidigung gegen SQL-Injection-Angriffe

[5] AppRadar™ for Microsoft SQL Server

[6] Secure Sphere

[7] AppDetective

[8] WebInspect

[9] Extended Stored Procedures Programmer's Reference (dab)