Der Klassiker unter den Web-Schwachstellen
SQL Injection gehört zu den bekanntesten und gefährlichsten Sicherheitslücken überhaupt. Bereits seit Ende der 1990er-Jahre taucht sie in Angriffen auf – und bis heute findet man sie in modernen Web-Apps, APIs und sogar mobilen Anwendungen. Der Grund: SQL-Datenbanken sind das Rückgrat vieler Systeme, und fehlerhafte Abfragen öffnen Hackern Tür und Tor.
Wie SQL Injection entsteht
Eine SQL-Injection entsteht, wenn eine Anwendung Nutzereingaben direkt in eine SQL-Abfrage einfügt, ohne diese Eingaben sauber zu validieren oder zu trennen. Die Datenbank kann dann nicht mehr unterscheiden: Ist das Teil einer legitimen Eingabe oder ein echter Befehl?
Ein einfaches Beispiel:
SELECT * FROM users WHERE username = 'alice' AND password = 'mypassword';
Wenn der Nutzer beim Login Folgendes eingibt:
- Username:
alice
- Passwort:
mypassword
funktioniert die Abfrage korrekt.
Doch wenn der Nutzer eingibt:
- Username:
' OR '1'='1
- Passwort:
anything
wird daraus:
SELECT * FROM users WHERE username = '' OR '1'='1' AND password = 'anything';
Da '1'='1'
immer wahr ist, liefert die Datenbank Ergebnisse zurück – und der Login wird ohne Passwortprüfung umgangen.
Erste Varianten von SQL Injection
1. Login-Bypass
Der Klassiker: Mit einem einfachen Payload wie ' OR '1'='1
lässt sich ein Login-Formular austricksen.
2. Union-Based SQLi
Angreifer nutzen den UNION
-Operator, um zusätzliche Datenbanken oder Tabellen abzufragen. Beispiel:
SELECT name, email FROM users WHERE id = '1' UNION SELECT creditcard, pin FROM payments;
So lassen sich fremde Tabellen „anhängen“ und Daten exfiltrieren.
3. Error-Based SQLi
Manche Datenbanken geben detaillierte Fehlermeldungen zurück. Angreifer fügen absichtlich falsche Eingaben ein, um über die Fehlermeldung Informationen über Tabellen, Spalten oder Versionen zu bekommen.
Beispiel:
' AND 1=CONVERT(int, 'text')--
Wenn die Datenbank einen Fehler meldet, enthält dieser oft wertvolle Details über den Aufbau der Datenbank.
4. Blind SQL Injection
Manchmal gibt es keine sichtbaren Fehlermeldungen. Angreifer nutzen dann logische Abfragen, die nur „wahr“ oder „falsch“ zurückliefern.
Beispiel:
?id=1 AND 1=1
?id=1 AND 1=2
Antwortet die Seite unterschiedlich (z. B. mit Inhalt vs. leere Seite), lässt sich Stück für Stück die Datenbankstruktur rekonstruieren.
Eine noch raffiniertere Variante: Time-Based Blind SQLi. Hier fügt man Befehle wie SLEEP(5)
ein. Wenn die Antwort fünf Sekunden verzögert kommt, weiß der Angreifer, dass sein Payload ausgeführt wurde.
Realistische Szenarien
- Datenlecks: Ein Angreifer zieht komplette User-Tabellen, inklusive Passwörter (oft unverschlüsselt).
- Manipulation: Inhalte in Tabellen lassen sich ändern – etwa Guthaben, Rollen oder Preise.
- Übernahme: Mit genug Wissen kann ein Angreifer sogar Betriebssystembefehle über die Datenbank ausführen (z. B. bei
xp_cmdshell
in Microsoft SQL Server).
Ein berühmter Fall: Der Sony Pictures Hack (2011), bei dem Millionen Nutzerdaten durch SQL Injection entwendet wurden.
Tools für SQL Injection
Viele Angreifer (und Pentester) nutzen Tools, um SQLi effizient auszunutzen:
- SQLMap: Automatisiert Tests, erkennt die Datenbank und führt Angriffe durch (Union, Blind, Time-Based usw.).
- Burp Suite: Zum Abfangen und Anpassen von Requests.
- Manuelle Tests: Mit Payloads aus Cheat Sheets (z. B. PayloadAllTheThings).
Wie man SQLi erkennt
Typische Indikatoren für SQLi:
- Unerwartete Fehlermeldungen wie “You have an error in your SQL syntax”.
- Unterschiede im Response, wenn man einfache Payloads ausprobiert (
'
,"
,--
,#
). - Lange Antwortzeiten → Hinweis auf Time-Based Injection.
- Unterschiede in Anzahl oder Inhalt der zurückgegebenen Ergebnisse.
Ein einfaches Vorgehen im Test:
- Eingabe eines
'
oder"
in Felder. - Prüfen, ob Fehlermeldungen auftauchen.
- Systematisch komplexere Payloads ausprobieren.
Schutzmaßnahmen gegen SQL Injection
1. Prepared Statements (Parametrisierte Queries)
Statt SQL-Abfragen mit String-Konkatenation zu bauen, setzt man Platzhalter und füllt sie mit Werten.
Beispiel in PHP (PDO):
$stmt = $pdo->prepare("SELECT * FROM users WHERE username = ? AND password = ?");
$stmt->execute([$username, $password]);
Die Eingaben werden nicht mehr als SQL interpretiert, sondern als reine Daten.
2. Stored Procedures (mit Vorsicht)
Stored Procedures kapseln Logik in der Datenbank. Sie können helfen – aber nur, wenn auch sie Eingaben korrekt parametrieren.
3. Input-Validierung
Nur erwartete Werte zulassen:
- Zahl erwartet → Nur Zahlen akzeptieren.
- Kurzer String erwartet → Länge beschränken.
4. Least Privilege
Der Datenbank-User, den die Anwendung nutzt, sollte nur minimale Rechte haben: SELECT, INSERT – aber kein DROP DATABASE.
5. Escape & Filter (ergänzend)
Escaping von Sonderzeichen kann helfen, ist aber kein Ersatz für Prepared Statements.
Warum SQLi immer noch existiert
Trotz jahrzehntelanger Aufklärung findet man SQLi nach wie vor – aus drei Gründen:
- Alte Legacy-Systeme ohne moderne Schutzmechanismen.
- Schnell entwickelte Apps, bei denen Sicherheit „vergessen“ wurde.
- Fehlendes Wissen bei Entwicklern über Prepared Statements.
Was du mitnehmen solltest
- SQL Injection ist alt, aber extrem gefährlich und noch immer verbreitet.
- Varianten reichen von Login-Bypass über Union-Queries bis zu Blind SQLi.
- Tools wie SQLMap machen Angriffe einfach – Schutz ist also entscheidend.
- Prepared Statements sind der Goldstandard, kombiniert mit Least Privilege und guter Input-Validierung.
Im nächsten Teil der Serie gehen wir über SQL hinaus und schauen uns Command Injection und NoSQL Injection an – zwei Varianten, die besonders in modernen Anwendungen relevant sind.
Schreibe einen Kommentar