studyklar
IProg · Skript 6 · Abschnitt 7

Prepared Statements mit mysqli

Ein Prepared Statement trennt den SQL-Text von den Werten. So kann keine Eingabe zu SQL-Code werden. Rechts wächst das Beispiel der Folie Zeile für Zeile, danach laufen Varianten und ein Angriff mit ihren Ausgaben, berechnet mit Beispieldaten. Mit Weiter geht es Schritt für Schritt voran.

Worum es geht

Skript 06, Folien 27–30: Prepared Statements, Binden, Vorteile.

Wird eine Eingabe in den SQL-Text kopiert, schreibt der Benutzer am SQL mit. Wie schickt man Werte so an die Datenbank, dass sie immer nur Werte bleiben?

Aus Skript 06, Folie 25: Mit $param = "CATS' OR 'X' = 'X" wird aus categoryid='$param' eine immer wahre Bedingung: Die Abfrage liefert alle Zeilen. Das heißt SQL-Injection.

So gehen wir vor:

  1. Platzhalter, prepare, bind_param, execute, Ergebnis lesen.
  2. Die Variante mit get_result und fetch_assoc.
  3. Die Typ-Buchstaben von bind_param.
  4. Warum der Angriff jetzt scheitert, und die Vorteile.
  5. Eine Klausurfrage dazu.

Ein Fragezeichen statt des Werts

$sql = 'SELECT productid, name        FROM Product WHERE categoryid = ?';

Der SQL-Text enthält keinen Wert mehr. An seiner Stelle steht ein Fragezeichen, ein Platzhalter. Auch die Hochkommas um den Wert fallen weg: Ob der Wert ein Text ist, regelt später bind_param.

Der Text steht in einfachen Hochkommas, damit PHP hier keine Variable einsetzt. Der Schutz vor SQL-Injection kommt aber erst dadurch, dass der Wert später getrennt zur Datenbank geht (Schritt 4 und Schritt 8).

Aus Skript 04, Folie 16: In doppelten Anführungszeichen setzt PHP Variablen ein, in einfachen nicht.

prepare: die Datenbank prüft den Text

$stmt = $db->prepare( $sql );

$db->prepare($sql) schickt den Text mit dem Platzhalter an die Datenbank. Sie analysiert ihn: Ist das gültiges SQL, gibt es Tabelle und Spalten? Das ist laut Notiz auf der Folie der erste Schritt.

Zurück kommt ein Statement-Objekt in $stmt: der vorbereitete Befehl, der noch auf seinen Wert wartet.

Noch 11 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

$sql =  "SELECT * FROM Product WHERE categoryid='$param'";$erg = $db->query( $sql );
LegendeZeilen des SchrittsVorher, Folie 25: Der Wert wird in den SQL-Text kopiert.