SQL Injections

Was sind SQL-Injections?
SQL-Injection (dt. SQL-Einschleusung, SQL-Injektion) bezeichnet das Ausnutzen einer Sicherheitslücke in Zusammenhang mit SQL-Datenbanken, die durch mangelnde Maskierung oder Überprüfung von Metazeichen in Benutzereingaben entsteht. Der Angreifer versucht dabei, über die Anwendung, die den Zugriff auf die Datenbank bereitstellt, eigene Datenbankbefehle einzuschleusen. Sein Ziel ist es, Daten in seinem Sinne zu verändern oder Kontrolle über den Server zu erhalten.

Ein kleines Beispiel
Hier ein kleines Beispiel. Wir nehmen an, dass wir in unserer Datenbank folgende Tabellen haben:

  • Tabelle News: Tabelle mit Newseinträgen, ingesamt 6 Spalten
  • Tabelle Users: Tabelle mit Benutzerdaten, Passwörter usw., ingesamt 8 Spalten

Unser Script (news.php) würde so aussehen:

<?php

// Code...

$query = mysql_query('SELECT * FROM News WHERE id = ' . $_GET['id']);
// Für eine Ausgabe... mag normalerweiße anders aussehen...
while ($row = mysql_fetch_array($query, MYSQL_ASSOC)) {
  foreach ($row as $key => $value) {
    echo "$key: $value";
  }
}

// Weiterer Code…

?>[/code]
Ruft der User die Datei per…

http://example.com/news.php?id=1

auf, so erscheint noch kein Fehler. Wird die Datei aber folgendermaßen aufgerufen…

http://example.com/news.php?id=1'

so würde MySQL diesen Fehler zurück liefern:

„You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near…“

Dies heißt in 99% der Fällen folgendes: Dieses Script ist angreifbar!

Was ist möglich?

http://example.com/news.php?id=-1337 UNION SELECT 1,DATABASE(),VERSION(),CONCAT(username,0x3a,password),5,6 FROM users

Hiermit würde man als Ausgabe den Namen der Datenbank, die MySQL Version sowie eine Liste mit den Userdaten, samt Passwort erhalten.

Statt dem -1337 könnte man auch 99999 oder sonst irgendeine beliebige Zahl verwenden. Sie ist nur zu einem Zweck da: Damit nur das Ergebnis aus der SQL Injection ausgegeben wird.

Die MySQL Funktion CONCAT() fügt mehrere Spalten und Zeichen zusammen. Hier verwandt, um eine Liste ala „Username:Passwort“ zu generieren.

Klar sein sollte, was DATABASE() bzw. VERSION() tut.

Wie kann ich mich schützen?
Alle Variablen vor dem senden an die Datenbank überprüfen (existent, leer?) und mit der Escape Funktion für die jeweilige Datenbank-Extension die „bösen Zeichen“ maskieren. In MySQL geht das folgendermaßen:

<?php

$id = mysql_real_escape_string($_GET['id']);
$query = mysql_query('SELECT * FROM News WHERE id = ' . $id);

?>

Einen Kommentar hinterlassen

Dein Kommentar