studyklar
IProg · Skript 9 · Abschnitt 3

JDBC: SQL-Injection und Prepared Statements

Eine Eingabe des Benutzers gehört nie direkt in einen SQL-Befehl. Hier steht, was dabei schiefgeht und wie ein PreparedStatement es verhindert. Mit Weiter geht es Schritt für Schritt voran. Ein Klick auf einen Schritt springt direkt dorthin.

Worum es geht

Skript 09, Folien 10 bis 12: Erinnerung SQL-Injection, Prepared Statements, Vorteile von Prepared Statements.

Programme bauen SQL-Befehle oft aus Text und einer Eingabe zusammen, etwa einer Produktnummer aus einem Formular. Die Frage dieses Abschnitts: Was kann ein Benutzer damit anrichten, und wie schreibt man es richtig?

Zum Ausprobieren nehmen wir eine Beispieltabelle Product mit drei Zeilen; sie steht nicht im Skript. pnr ist die Produktnummer, categoryid die Kategorie.

Aus Skript 09, Folie 8: Dort entsteht das SQL als Text: "… WHERE categoryId = " + cid. Ausgeführt wird es mit executeQuery, gelesen mit while (rs.next()).

So gehen wir vor:

  1. Drei Eingaben in einen zusammengeklebten Befehl einsetzen.
  2. Denselben Befehl mit Platzhalter schreiben.
  3. Prüfen, dass der Angriff jetzt ins Leere läuft.
  4. Die Vorteile von Prepared Statements.
  5. Eine Klausurfrage dazu.

Abweichung vom Skript: Folie 11 nennt die Produktnummer productid, Folie 10 pnr. Wir bleiben überall bei pnr.

Die Eingabe wird Teil des Befehls

String seltext =    "SELECT * FROM Product WHERE pnr=" + x;
SELECT * FROM Product WHERE pnr=234

Folie 10 hängt die Eingabe x an den SQL-Text an. Gibt der Benutzer 234 ein, entsteht ein gewöhnliches SELECT. Es findet genau eine Zeile: das Produkt 234, den Tisch.

Die Datenbank bekommt nur den fertigen Text. Sie kann nicht erkennen, welcher Teil vom Programmierer stammt und welcher vom Benutzer.

x = 234 OR 1 = 1: alle Zeilen

SELECT * FROM Product WHERE pnr=234 OR 1 = 1

Jetzt tippt jemand 234 OR 1 = 1. Im Befehl steht dann WHERE pnr=234 OR 1 = 1. 1 = 1 ist immer wahr, also ist die ganze Bedingung für jede Zeile wahr. Das SELECT liefert alle drei Zeilen.

Das nennt man SQL-Injection: Eine Eingabe schmuggelt eigenes SQL in den Befehl und ändert seine Bedeutung.

Noch 10 Schritte bis zum Ergebnis
Den ganzen Lösungsweg sehen Studierende und Lehrende der HS KL. Registriere dich mit deiner Adresse @stud.hs-kl.de oder @hs-kl.de, dann geht es hier direkt weiter.

Abbildung 1

pnrnamecategoryid
234Tisch47
235Stuhl47
236Lampe12
LegendeZeilen des SchrittsDie Beispieltabelle Product mit drei Zeilen.