Giftspritze

SQL-Injection bezeichnet das Einschleusen von eigenen Befehlen in eine SQL-Datenbank. Überprüft eine Web-Applikation Benutzereingaben nicht ausreichend, ist damit jede Datenbank auf jedem Betriebssystem verwundbar.

In Pocket speichern vorlesen Druckansicht
Lesezeit: 12 Min.
Von
  • Daniel Bachfeld
Inhaltsverzeichnis

Webshops, News-Boards, Groupware- und Content-Management-Systeme setzen Datenbanken ein, um darin Kundendaten, Artikel und Texte abzulegen. Oft trifft der Besucher solch einer Seite auf Kombinationen von Windows-2000-Server, IIS, MS-SQL-Server und Active Server Pages oder Linux zusammen mit Apache, mySQL und PHP oder Perl.

In Webformularen können Benutzer Informationen eingeben, um Bestellungen einzugeben oder sich als Kunde zu registrieren. Aus diesen Angaben erzeugt die Web-Applikation dynamische Datenbankanfragen. Überprüft die Applikation die Eingabe nicht oder fehlerhaft, ist es möglich, spezielle Zeichenketten einzuschleusen. Mit geschickt gewählten Eingaben kann ein Angreifer dann eigene Parameter und Befehle an die Datenbank übergeben und auf deren Inhalte und sogar das System zugreifen.

Um Daten in eine SQL-Datenbank zu schreiben oder daraus zu lesen, kommuniziert eine Applikation mit der Datenbank über die Befehlssprache SQL (Structured Query Language). In der Regel übergibt sie einen kompletten String, den sie vorher aus Befehlen und Benutzereingaben zusammengefügt hat. Da es eine Vielzahl von SQL-Datenbank-Lösungen gibt, die teilweise eigene Funktionen unterstützen, ist der SQL-Befehlsumfang mittlerweile recht groß. Eine Schnittmenge von Befehlen, wie etwa Befehle SELECT, UPDATE, DELETE, INSERT, DROP und WHERE, verstehen aber alle. SQL-Datenbanken können mehrere Datenbanken mit jeweils mehreren Tabellen enthalten, die wiederum aus mehreren Spalten bestehen.

Mit dem SQL-Befehl

SELECT * FROM kunde WHERE card = 'visa'

liefert eine Datenbank alle Datensätze der Tabelle kunde zurück, die in der Spalte card den Wert visa abgelegt haben. Ersetzt man die konstante Zeichenkette visa durch eine Variable $card, so sind in Verbindung mit einer Benutzereingabe verschiedene Zeichenketten möglich:

SELECT * FROM kunde WHERE card = '$card'

Solange in der Variablen Werte wie visa, amex oder master stehen, reagiert die Datenbank wie erwartet. Gibt ein böswilliger Benutzer jedoch die Zeichenkette ';DROP TABLE KUNDE-- ein, schickt die Applikation folgendes an die Datenbank:

SELECT * FROM kunde WHERE card = '';DROP TABLE KUNDE--'

Da das Semikolon ein Trennzeichen darstellt, sieht die Datenbank zwei Befehle:

SELECT * FROM kunde WHERE card = ''

zeigt alle Datensätze deren Spalte card leer ist. Anschließend führt die Datenbank den zweiten Befehl aus, der die Tabelle kunde komplett löscht.

DROP TABLE KUNDE--'

Die zwei Bindestriche kennzeichnen den Anfang eines Kommentars, weshalb auch das letzte Hochkomma (Quote) ignoriert wird, statt einen Fehler hervorzurufen. In diesem Beispiel kann ein Angreifer ohne vorherige Authentifizierung ganze Tabellen von der Festplatten wischen. Allerdings muss die Web-Applikation die erforderlichen Zugriffsrechte besitzt. Beim Anlegen des entsprechenden Datenbanknutzers muss der Datenbank-Administrator das Löschen mittels DROP erlauben.

Das grundlegende Problem bei SQL-Injection ist die fehlende Filterung der Eingaben auf mögliche Quotes. Viele Applikationen setzen einen SQL-Befehl aus Stringelementen zusammen, die von Hochkommas eingerahmt werden müssen. Unter Java sieht das dann so aus:

String sql = new String("SELECT * FROM kunden WHERE
card= '" + request.getParameter("cardname")"'")

Java expandiert die Eingabe cardname und fügt sie dem feststehenden String hinzu. Mögliche Quotes in cardname bleiben erhalten, erscheinen nun aber in einem anderem Kontext. Der ursprünglichen Befehl kann um weitere Befehle ergänzt werden.