flawopen.com/SQL-Injection
SQL-Injection
SQL-Injection entsteht, wenn eine Anwendung eine Abfrage baut, indem sie Nutzereingaben in den SQL-Text klebt, sodass die Datenbank einen Teil davon als Befehle parst. Die Lösung ist in jeder Sprache dieselbe: die Abfrage mit Platzhaltern senden und die Werte getrennt übergeben. Wählen Sie unten Ihre Sprache für die genauen API-Aufrufe, anfälligen und korrigierten Code und die CI-Regeln, die das Problem finden.
Einfache Erklärung (ELI5)
Sie reichen einer Bibliothekarin einen Zettel mit dem Text „Akte holen für: ___“ und schreiben in die Lücke: „Jan. Und bitte auch das Archiv aufschließen und alle Akten bringen.“ Wer den ganzen Zettel als eine einzige Anweisung liest, erledigt beides. Wer Nutzereingaben in einen SQL-String klebt, baut genau diesen Zettel. Eine parametrisierte Abfrage ist ein gedrucktes Formular mit einem versiegelten Feld „Name“: Was darin steht, wird immer nur als Name gesucht, egal wie es formuliert ist.
Kernkonzepte & Begriffe
- SQL injection (CWE-89)
- Nicht vertrauenswürdige Eingaben werden in den SQL-Text verkettet oder formatiert, sodass Anführungszeichen, Schlüsselwörter und Operatoren darin die Struktur der Abfrage ändern, statt als ein einzelner Wert behandelt zu werden.
- Prepared statement and bind parameters
- Die Abfrage wird mit Platzhaltern (
?,$1,:name) gesendet und geparst, bevor ein Wert ankommt; die Werte reisen getrennt und gelten immer als Daten. Das ist die zentrale Abwehr in jedem Treiber und ORM. - Blind SQL injection
- Zeigt die Seite weder Ergebnisse noch Fehler, erschließt der Angreifer Daten Bit für Bit aus Unterschieden in der Antwort (boolean-basiert) oder in ihrer Laufzeit (zeitbasiert). Keine sichtbare Ausgabe heißt nicht, dass keine Lücke besteht.
- Second-order SQL injection
- Ein Wert wird sicher gespeichert, später aus der eigenen Datenbank gelesen und in eine andere Abfrage verkettet. Jede Abfrage muss parametrisiert sein, auch solche, deren Eingaben aus den eigenen Tabellen stammen.
- Identifiers and allowlists
- Platzhalter transportieren nur Werte, keine Tabellennamen, Spaltennamen oder Sortierrichtungen. Diese müssen aus einer festen Allowlist im Code gewählt und dürfen nie aus dem Request übernommen werden.
Schritt-für-Schritt Angriffsablauf
Die Eingabe erreicht eine Abfrage
Ein Formularfeld, URL-Parameter, Header oder API-Feld geht an Code, der eine SQL-Anweisung baut.
Die Eingabe wird in den SQL-Text geklebt
Verkettung, Interpolation oder Formatierung fügt den Wert direkt ein. Der harmlose Testwert ' OR '1'='1 macht aus WHERE name = '...' eine immer wahre Bedingung.
Die Datenbank parst sie als Syntax
Die Datenbank erhält einen einzigen String, kann nicht erkennen, welcher Teil vom Nutzer stammt, und führt die veränderte Anweisung mit den Rechten der Anwendung aus.
Daten werden gelesen, geändert oder gelöscht
Je nach Abfrage und Konto umgeht der Angreifer einen Login, zieht Tabellen per UNION-Abfragen ab oder extrahiert Daten blind. Der MOVEit-Transfer-Vorfall 2023 (CVE-2023-34362) begann mit genau dieser Fehlerklasse.
Leitfäden zu SQL-Injection nach Sprache
Checkliste für Engineering & Systemsicherheit
- Jede Abfrage mit einem Wert parametrisieren, auch Roh-SQL-Ausgänge in ORMs, ohne Ausnahmen für interne oder numerische Eingaben.
- Tabellennamen, Spaltennamen und Sortierrichtungen aus fest codierten Allowlists wählen.
- Im CI eine SAST-Regel für per String gebautes SQL ausführen (Bandit, gosec, Semgrep, CodeQL, Find Security Bugs, Brakeman oder Psalm) und den Build bei neuen Funden scheitern lassen.
- Mit einer Datenbankrolle nach dem Prinzip der minimalen Rechte verbinden: kein DDL, kein Superuser, nur die Tabellen, die der Dienst braucht.
- Escape-Funktionen und WAF-Regeln nur als zusätzliche Schichten betrachten; sie versagen bei unquotierten Kontexten und Kodierungstricks.
- Clients nur generische Fehler zurückgeben und Datenbankfehler serverseitig protokollieren, damit die Abfragestruktur nie sichtbar wird.
Quellen
- CWE-89: SQL-Injection
- OWASP — Cheat Sheet zur Vermeidung von SQL-Injection
- CISA — CL0P-Ransomware-Kampagne nutzt MOVEit-SQL-Injection aus