Wie ein Suchfeld eine Datenbank verrät
SQL-Injection ist ein Angriff, bei dem jemand eigenen SQL-Text in ein Eingabefeld schreibt und die Datenbank ihn ausführt. So kommen Angreifer an Daten, die sie nie sehen sollten.
Wer weiß, wie es geht, kann es mit einer einzigen Änderung verhindern. Die Regel: Du übst nur am Shop deiner eigenen Lab-Kopie, nie an einer fremden Seite und nie ohne Erlaubnis.
Am Ende dieser Lektion
Notiz
Ich kann zeigen, wie SQL-Injection funktioniert, und sie mit einer parametrisierten Abfrage beheben.
Schlüsselwörter
| Begriff | Was er bedeutet | Beispiel |
|---|---|---|
| SQL | die Sprache, mit der man eine Datenbank fragt | |
| Abfrage | eine Frage an die Datenbank, als SQL-Text | SELECT name FROM produkte |
| Injection | Einschleusen von fremdem Text in eine Abfrage | |
| Parameter | ein Platzhalter für einen Wert in der Abfrage | ? |
| Eingabe | Text, den ein Mensch in ein Feld tippt | |
| Maskierung | Sonderzeichen so behandeln, dass sie harmlos sind |
Die Zellen, die Lernende ausfüllen, bleiben in dieser Vorschau leer.
Wo liegt der Fehler?
Ein Shop sucht Produkte mit einer Abfrage wie SELECT name FROM produkte WHERE name LIKE '%Stift%'. Der Suchbegriff wird einfach in den SQL-Text hineingeklebt.
Der Fehler: Die Datenbank kann nicht unterscheiden, was der Programmierer geschrieben hat und was die Nutzerin getippt hat. Alles ist für sie ein einziger Text.
Was die Datenbank wirklich bekommt
begriff = "x' OR 1=1 --"
abfrage = "SELECT name FROM produkte WHERE name LIKE '%" + begriff + "%'"
print(abfrage)
# Ändere den Begriff in "Stift" und starte noch einmal.
Was bewirkt das Hochkomma?
Das Hochkomma beendet die Zeichenkette in der Abfrage. Danach beginnt neuer SQL-Text, den jemand anderes gewählt hat. OR 1=1 ist immer wahr, also passt jede Zeile. -- macht den Rest zum Kommentar.
Ergebnis: Die Suche liefert auch Zeilen, die nicht öffentlich sein sollten.
Wie behebt man es?
Mit einer parametrisierten Abfrage. Der SQL-Text enthält nur einen Platzhalter, ?. Der Wert wird getrennt übergeben.
Die Datenbank behandelt den Wert dann immer als Daten, nie als Befehl. Selbst ein Hochkomma in der Eingabe ist nur ein Zeichen im Suchtext.
Dieselbe Suche, sicher gebaut
import sqlite3
db = sqlite3.connect(":memory:")
db.execute("CREATE TABLE produkte (name TEXT, oeffentlich INTEGER)")
db.execute("INSERT INTO produkte VALUES ('Stift', 1)")
db.execute("INSERT INTO produkte VALUES ('Geheimer Prototyp', 0)")
begriff = "x' OR 1=1 --"
abfrage = "SELECT name FROM produkte WHERE oeffentlich = 1 AND name LIKE ?"
zeilen = db.execute(abfrage, ("%" + begriff + "%",)).fetchall()
print(zeilen)
# Ändere den Begriff in "Stift" und starte noch einmal.
Ein häufiger Fehler
Warnung
Viele denken, es reiche, Hochkommas aus der Eingabe zu entfernen. Das ist unsicher, denn es gibt viele andere Tricks, und Namen wie O'Brien gehen dann kaputt. Nutze immer Parameter. Dann musst du nichts entfernen.
Die eine Regel
Warnung
Drück oben auf Lab starten und warte, bis der Shop läuft. Der Shop ist deine eigene Kopie und hat keinen Weg ins Internet. Richte nie ein Werkzeug gegen eine Seite, die dir nicht gehört.
Normal nach „pen“ suchen
curl -G --data-urlencode "q=pen" http://app:8000/searchHier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.
Nach allen Produkten mit „a“ suchen
curl -G --data-urlencode "q=a" http://app:8000/searchHier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.
Nach etwas suchen, das es nicht gibt
curl -G --data-urlencode "q=xyz" http://app:8000/searchHier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.
Was die normale Suche zeigt
Der Shop antwortet mit einer Zeile je Treffer: der Name, zwei Leerzeichen und der Preis. Die Suche nach „pen“ liefert eine Zeile, die nach „a“ liefert zwei, und „xyz“ liefert gar nichts.
So sieht eine gesunde Suche aus. Ob der Shop auch mehr verrät, als er sollte, findest du als Aufgabe des Labs heraus. Dort baust du auch die Reparatur ein.