SQL-Injection verstehen und vermeiden
SQL-Injection verstehen und vermeidenEine Einführung für PHP-Anwendungen
Was ist eine SQL-Injection?
Eine SQL-Injection ist eine der gefährlichsten Schwachstellen in datenbank-basierenden Webanwendungen. Sie tritt auf, wenn Benutzereingaben ungefiltert in SQL-Datenbankabfragen eingebaut werden. Ein Angreifer kann so eigene SQL-Befehle einschleusen und z. B. vertrauliche Daten auslesen, löschen oder manipulieren.
Beispiel einer unsicheren Abfrage:
$unsafe_query = "SELECT * FROM users WHERE email = '" . $_GET['email'] . "'";
Gibt ein Angreifer als Parameter einer PHP-Seite z. B. ein:
?email=' OR 1=1
wird daraus der SQL-Befehl
"SELECT * FROM users WHERE email = '' OR 1=1"
Die WHERE-Klausel wird also unwirksam, da der logische Vergleich 1=1 stets wahr ist.
Daher werden alle Benutzer werden angezeigt.
Als Parameter sind weitere SQL-Anweisungen möglich, die realen Schaden, bis hin zu Datenverlusten, anrichten können.
Wie kann man SQL-Injection in PHP vermeiden?
- Prepared Statements (empfohlen!)
Verwendung von vorbereiteten SQL-Befehle mit Platzhaltern. Automatisches Escaping schützt vor Manipulation. - Eingabevalidierung
Stellt sicher, dass Benutzereingaben nur erlaubte Werte enthalten (z. B. E-Mail-Format, Zahlen etc.). - Whitelisting
Bei dynamischen Parametern (z. B. Sortierung) sollten nur vordefinierte Werte erlaubt werden.
Best Practice mit mysqli:
$mysqli = new mysqli("localhost", "user", "pass", "datenbank");
$stmt = $mysqli->prepare("SELECT * FROM users WHERE email = ?");
$stmt->bind_param("s", $_GET['email']);
$stmt->execute();
$result = $stmt->get_result();
while ($row = $result->fetch_assoc()) {
echo $row['name'];
}
Best Practice mit PDO:
$pdo = new PDO("mysql:host=localhost;dbname=datenbank", "user", "pass");
$stmt = $pdo->prepare("SELECT * FROM users WHERE email = ?");
$stmt->execute([$_GET['email']]);
foreach ($stmt as $row) {
echo $row['name'];
}
Weitere Information zu 'Prepared Statements':
Fazit:
Eine SQL-Injection ist leicht vermeidbar, wenn man bewährte Methoden wie Prepared Statements anwendet.
Alte Methoden mit Stringverkettung einzel gefilterter Parameter sollten wenn möglich vermieden werden.
u schnell übersieht man im eigenen Filter ein problematisches Zeichen, vor allem wenn noch Zeichensatzabhängigkeiten hinzukommen.
Prepared Statements innerhalb des PHP-Codes erlauben eine sichere Vorgehensweise.