Wenn der Kunde statt Daten Löschbefehle schickt

Mit einer einzigen Zeile SQL-Code, die auf die beschriebene Art injiziert worden ist, kann eine gesamte Datenbank ausgelesen werden – Kreditkartennummern inklusive.

Datenbanken sind die Seele des Geschäfts, auch in der digitalen Ökonomie. Ohne Zusammenspiel von Web-Anwendung und Datenhaltungssystem gibt es kein vernünftiges E-Business. Doch auch hier gilt: “No gain without pain.” Die enge Symbiose zwischen Backend und Frontend zieht ihre ganz speziellen Sicherheitsprobleme nach sich. Sind Webservices durch ihre nicht-hierarchische, offene Kommunikationsform ohnehin nicht einfach gegen digitale kriminelle Akte zu schützen, verführt die flexible und leicht anzuwendende Struktur der Datenbankabfragesprache SQL viele Hacker dazu, diesen Komfort für betrügerische oder zerstörerische Zwecke auszunutzen.
SQL wurde ganz speziell dafür entwickelt, auf Tabellen und Datensätzen relational organisierter Datenbanksysteme schnell und komfortabel operieren zu können. Mit SQL-Anweisungen lassen sich in quasi-natürlichsprachlicher Weise Datensätze einfügen und nach genau spezifizierten Kriterien auswählen, neue Tabellen anlegen oder bestehende löschen, oder auch auf der Basis von Vergleichsoperationen Datensätze zusammenführen oder löschen. Darüber können bestehende Tabellenstrukturen nach bestimmten Sichten aufbereitet werden.

Strukturiertes Pidgin-Englisch

SQL ist in seinen Grundstrukturen schnell zu lernen, da es ein strukturiertes Pidgin-Englisch darstellt:
SELECT KUNDENNAME, KUNDE_TELEFON FROM KUNDE WHERE BUNDESLAND =  ´Bayern´ AND UMSATZ > 10 000.

Auch jemand ohne SQL-Kenntnisse wird mehr oder weniger korrekt dechiffrieren können, dass diese SQL-Anweisung die Namen und Telefonnummern aller Kunden in Bayern aus der Datenbank ausgibt, die einen Umsatz von mehr als 10.000 Euro gebracht haben.

SQL büßt nichts von seinem technischen Charme ein, wenn man hinzufügt, dass die volle Syntax der Sprache recht komplex ist. Viele Anwender wollen halt doch recht komplexe Dinge mit einer Datenbankabfragesprache anstellen. SQL enthält deshalb beispielsweise in der Gestalt von so genannten Speicherprozeduren auch Elemente, wie man sie von prozeduralen Programmiersprachen kennt. Im Wesenskern ist SQL aber deskriptiv, das heißt die Anwender geben nicht wie in prozeduralen Sprachen Rezeptanweisungen, wie eine bestimmte Aufgabe gelöst werden soll, sondern beschreiben mit den Anweisungen, was sie wollen.

SQL-Befehle, wo Daten erwartet werden

Im Rahmen von Web-Applikationen werden nun prozedurale Elemente bestimmter Programmier- oder Skriptsprachen (etwa Active Server Pages, ASP) mit SQL-Anweisungen gekoppelt. Beispielsweise können über eine ASP-Anwendung Benutzereingaben (‘Name’, ‘Vorname’ etc.) abgefragt werden, die dann mit Hilfe der hinter der Webapplikation liegenden Datenbank verifiziert werden. Für diese Abfrage werden die eingegebenen Benutzerinformationen in entsprechende SQL-Statements eingefügt.

Genau an dieser Stelle des Geschäftsablaufes besteht nun ein erhebliches Gefährdungspotenzial durch die Möglichkeit, destruktiven oder manipulatorischen SQL-Code in die Datenbankabfrage einzuschleusen (so genannte SQL Injection).  Das passiert genau dann, wenn ein bösartiger Benutzer über den Verifikationsprozess nicht etwa Name, Vorname und eventuelles Passwort eingibt, sondern zum Beispiel eine Mischung aus Leer-Statements und inhaltlich leeren, aber logisch wahren Sätzen. Falls bei der Programmierung der Datenbankabfragen nicht sehr sorgfältige Präventivmaßnahmen gegenüber allen möglichen Versuchen, destruktivem SQL-Code einzuschleusen, unternommen worden sind, arbeitet die Datenbank ganz brav die betrügerisch eingeschleuste SQL-Anweisung ab.

Mit einer einzigen Zeile SQL-Code, die auf die beschriebene Art injiziert worden ist, kann beispielsweise die gesamte Datenbank ausgelesen werden (Kreditkartennummern inklusive), oder es können Tabellen vollständig gelöscht werden (‘DROP Tabelle KUNDEN’). Und wenn sich ein Angreifer auf Speicherprozeduren wie ‘xp_cmdshell’ Zugriff verschaffen kann, kann er sogar Befehle auf Betriebssystemebene ausführen. Das Teuflische an der Sache besteht darin, dass das Einschleusen von destruktivem SQL-Code auf viele verschiedene Weisen geschehen kann. Ständig finden versierte Betrüger und Eindringlinge neue Varianten.

Fehlermeldungen als Sprungbrett

Die Betreiber einer Web-Anwendung müssen sich darüber im Klaren sein, dass auch im Bereich der SQL-Injektion nach dem Stopfen einer Lücke die nächste Angriffsvariante schon wartet. Manchmal wird zum Beispiel der Einsatz von parametrierten Speicherprozeduren als Schutzmaßnahme empfohlen, doch neuere Untersuchungen über SQL-Injektion zeigen, dass auch die vermeintlich sicheren Speicherprozeduren erfolgreich angegriffen werden können (1).

Viele Angriffe auf Datenbanken führen zunächst einmal zu Fehlermeldungen. Doch Fehlermeldungen sind für den ‘echten Hacker’ nicht gleichbedeutend mit “Fehlanzeige”. Enthalten diese doch wertvolle Informationen. Dadurch führen sie den geduldigen und versierten Eindringling nicht selten über scheinbare Umwege doch noch zum Ziel. Zum Beispiel mit so ‘schnieken’ Features wie dem LIKE-Prädikat von SQL. Wenn in der Datenbank der Benutzername ‘admin’ abgelegt ist (durchaus wahrscheinlich), dann kann es durchaus funktionieren, dass der Hacker nach der Eingabe einer Anweisung der Art ‘or Benutzer.Name LIKE ‘a%’— auf einmal als Administrator eingeloggt ist. Nicht schlecht! Oder doch?

Einen hundertprozentigen Schutz gegen das Ausspähen beziehungsweise Manipulieren oder Zerstören von Datenbankinhalten durch SQL-Injektion gibt es nicht. Neben einer möglichst sorgfältigen Programmierung, die zumindest die bekanntesten Einfallstore schließt (“keine Benutzereingaben direkt in WHERE-Klauseln zulassen”), ist wohl eine sehr restriktive Handhabung der Rechte, wer auf welche Daten zugreifen darf, die beste Vorsorgemaßnahme.