SQL-Injection bezeichnet die Möglichkeit durch Benutzereingaben eine Sicherheitslücke im System auszunützen um Daten einer SQL-Datenbank zu verändern oder auszulesen. Dadurch ist es möglich kritische Informationen, wie Benutzernamen und Passwörter, aus der zugrundeliegenden Datenbank auszulesen.

Login-Seiten von Webseiten haben in der Regel ein Benutzereingabefeld und ein Passwortfeld. Wenn die Eingaben der Felder nicht geprüft werden, so kann es z.B. möglich sein, sich ohne gültiges Passwort anzumelden.

Als erstes wird jedoch überprüft, ob die Benutzereingaben überprüft werden. Dies wird durch einen einfachen Slash (‚) im Eingabefeld realisiert.

Beispiel 1:
Wir gehen von dem zugrundeliegenden SQL-Befehl aus:

select FELDER
from TABELLE
where FELD = ‚$name‘;

Geben wir nun in das Eingabefeld otto‘ ein, so dürfte ohne Prüfung der Eingabe der SQL-Befehl folgendermaßen aussehen:

select FELDER
from TABELLE
where FELD = ‚otto“;

Da dies kein gültiger SQL-Befehl ist, bricht der SQL-Parser mit einer Fehlermeldung ab. Wie dies dem Benutzer angezeigt wird, hängt natürlich von der zugrundeliegenden Anwendung ab. Jedoch ist es wahrscheinlich, dass die Fehlermeldung direkt im Browser erscheint.
Bekommen wir eine solche Meldung angezeigt, so wissen wir, dass die Parameter nicht auf Sonderzeichen geprüft werden und SQL Injection möglich ist.

SQL-Injection ist nicht nur bei Eingabefeldern möglich, sondern auch bei URL-Parametern, die über die URL mitgegeben werden.

Beispiel 2:
Wir haben die URL http://webserver.de/suche.php?ID=87. Hier ist es ein leichtes einfach beim ID-Parameter einen anderen Wert einzugeben. Legt man hier ebenfalls einen SQL-Befehl zugrunde, dem die ID ohne Prüfung übergeben wird, so besteht hier ebenfalls die Möglichkeit von SQL-Injection.

Durch die Möglichkeiten von SQL-Injection ist es nun möglich sich Informationen aus der Datenbank zu verschaffen bzw. zu ändern oder zu löschen.

Beispiel 3:
Wir haben wieder den SQL-Befehl aus Beispiel 1 und geben nun in das Eingabefeld den Wert otto‘ or ‚x’=’x ein. Daraus ergibt sich nun:

select FELDER
from TABELLE
where FELD = ‚otto‘ or ‚x’=’x‘;

Da die zweite Bedingung ‚x’=’x‘ immer gültig ist, liefert der SQL-Befehl alle Einträge der Datenbank-Tabelle zurück. Je nachdem wie die Anwendung aufgebaut ist, liefert sie den ersten Eintrag oder alle Einträge zurück.

Kommt der Anwender von SQL-Injection an bestehende Tabellennamen heran, kann er diese auch Löschen.

Beispiel 4:
Dazu benutzt er das Eingabefeld und gibt bspw. otto‘; drop table TABELLE; — ein.
Der resultierende SQL-Befehl hat dann folgendes Aussehen:

select FELDER
from TABELLE
where FELD = ‚otto‘; drop table TABELLE; –‚

Strichpunkte beenden einen SQL-Befehl. Danach kann ein anderer SQL-Befehl angegeben werden. Hier wollen die Tabelle TABELLE löschen. Das — sind bei SQL-Befehlen Kommentarzeichen und ignorieren somit weitere SQL-Befehle, z.B. das abschließende ‚ das der SQL-Befehl am Ende normalerweise hat.
Natürlich kann der SQL-Befehl nur erfolgreich durchgeführt werden, wenn der Datenbankbenutzer Schreibrechte auf die Datenbank besitzt.

Um an Tabellennamen in der Datenbank zu kommen, kann ebenfalls das Eingabefeld benutzt werden. Es wird bspw. versucht ein UNION auf eine andere Tabelle zu machen.

Beispiel 5:

select FELDER
from TABELLE
where FELD = ‚otto‘ union select ‚x‘ from TABELLE_2; –‚

Durch die Eingabe otto‘ union select ‚x‘ from TABELLE_2; — wird versucht TABELLE_2 zu finden. Kommt der SQL-Befehl ohne Fehlermeldung zurück, so scheint es die Tabelle in der Datenbank zu geben. Falls es zu einem Fehler kommt kann man einen anderen Tabellennamen versuchen. Mit automatischen Skripten sind gültige Tabellennamen schnell gefunden.
Die einzige Schwierigkeit ist herauszufinden wieviele Rückgabefelder der SQL-Befehl hat und den Union daraufhin anzupassen, um einen gültigen SQL-Befehl zu bekommen.

Vermeidung von SQL-Injection:
Um diese Fehlerquelle und Sicherheitslücke zu beseitigen, müssen alle Eingaben, die der Benutzer beeinflussen kann auf Sonderzeichen überprüft werden.

PHP:
Hier gibt es in den Konfigurationsparameter magic_quotes_gpc, der jedoch nicht verwendet werden soll. Generell ist es besser die Überprüfung selbst vorzunehmen. Kommt der Konfigurationsparameter magic_quotes_gpc und zusätzlich eine eigenständige Entwertung der Sonderzeichen zum Einsatz, kann dies zu doppelter Entwertung von Sonderzeichen führen. Dadurch kann es eventuell zu Verfälschungen bei SQL-Befehlen kommen. Es ist besser die Entwertung immer selbst vorzunehmen und sich nicht auf einen Konfigurationsparameter zu verlassen, der auf anderen Systemen anders eingestellt sein könnte.

Beispiel (Entwertung für SQL-Abfragen an einen Mysql-Datenbank durch die Funktion mysql_real_escape_string):

$query = „select FELDER from TABELLE where FELD = ‚“.mysql_real_escape_string($name).“‚“;
$result = mysql_query($query) or die „Abfrage fehlgeschlagen“;

Beispiel (Entwertung durch PreparedStatement):

$stmt = $dbh->prepare(„select FELDER from TABELLE where FELD = :name);
$stmt->bindParam(„:name“, $name);
$stmt->execute();

Beispiel (Entwertung durch PHP Data Objects ab PHP 5.1):

$dbh->exec(„select FELDER from TABELLE where FELD = „.$dbh->quote($name,PDO::PARAM_STR));

Java:
Beispiel (Entwertung durch PreparedStatement):

PreparedStatement stmt = conn.prepareStatement(„select FELDER from TABELLE where FELD = ?“);
stmt.setString(1, name);
ResultSet rslt = stmt.executeQuery();

 Antworten

   
Impressum Suffusion theme by Sayontan Sinha