Datenbankzugriff mit Java

SQL Injections und Prepared Statements

xkcd 327 - Exploits of a mom

https://xkcd.com/327

Was geht da schief?

Input Sanitization

"Vertraue niemals darauf, dass eine Benutzereingabe dem entspricht, was du erwartest"

A software tester walks into a bar. Runs into a bar. Crawls into a bar. Dances into a bar. Flies into a bar. Jumps into a bar.
And orders: A beer. 2 beers. 0 beers. 99999999 beers. A lizard in a beer glass. -1 beer. "qwertyuiop" beers.
Testing complete. A real customer walks into the bar and asks where the bathroom is. The bar goes up in flames.

Lösungsansätze

  • Benutzereingaben müssen von SQL-Befehlen getrennt behandelt werden
  • SQL-Befehle werden dazu mit Parametern (Platzhaltern) vorbereitet ("prepared")
  • Den Parametern werden dann die Benutzereingaben zugewiesen, dabei kann eine Input Sanitization durchgeführt werden - es wird also geprüft, ob die Eingabe als Ersetzung für den Parameter erlaubt ist
  • Beim Ausführen werden die Parameter dann durch die bereinigten Nutzereingaben ersetzt

Wie geht's? Prepared Statements

import java.sql.PreparedStatement;
// [...]

PreparedStatement statement = DBConnection.prepareStatement(
  "SELECT * FROM benutzer WHERE username = ? AND password = ?"
); // ? als Platzhalter, keine Anführungszeichen

// username und passwd werden vom Benutzer eingegeben
statement.setString(1, username);
statement.setString(2, passwd);

ResultSet result = statement.executeQuery();
// [...]
}