PHP : Sicherheit

SQL Injections vermeiden

von treo

Was ist eine SQL Injection?

Eine SQL Injection nennt man das Einfügen von SQL Kommandos die an dieser Stelle nichts zu suchen haben. Um dies zu verdeutlichen hier ein kleines Beispiel:

Man will die einen Datensatz mit einer ID auslesen die man aus der URL bekommt. Man hat also eine Url wie diese hier: index.php?id=5 Im PHP Code baut man sich nun seine SQL Query zusammen:


$query = "SELECT * FROM `tabelle` WHERE `id`='".$_GET['id']."';";

Man erwartet eigentlich nichts anderes als Zahlen an dieser Stelle, man denkt also dass man eine solche Query haben wird:


SELECT * FROM `tabelle` WHERE `id`='5';

Was ist aber nun wenn jemand etwas anderes als eine Zahl angibt: index.php?id=peter Nun dann wird die Query so aussehen:


SELECT * FROM `tabelle` WHERE `id`='peter';

Ok, denkt man sich dann, ich hab keine id die sich 'peter' nennt, ist doch kein Problem!? Doch es ist ein Problem, denn man könnte auch SQL Befehle einschleusen, so könnte man wenn man statt einer Zahl nun SQL Befehle der Variable $_GET['id'] zuweißt eben diese SQL Befehle ausführen lassen. Jetzt denkt sich der normale Benutzer sicher: "Aber ich hab das ganze doch in Anfürungszeichen gesetzt, das wird doch nur als String gesehen!" Nun das ist eine doch sehr naheliegende Überzeugung, aber wenn man bisschen weiter denkt falsch. Schauen wir uns mal genauer an was passiert wenn man das script mit ?id='; DROP `datenbank`;-- aufruft. Es wird nun diese Query erzeugt:


SELECT * FROM `tabelle` WHERE `id`=''; DROP DATABASE `datenbank`;--';

Wie man sieht schließt das erste '; unsere Query vorzeitig ab, und schickt direkt ein DROP DATABASE `datenbank`; hinterher welches die Datenbank `datenbank` vollständig löscht. Abschließend wird noch -- dahinter geschoben, dies sorgt dafür dass alles was danach steht als Kommentar angesehen wird. Dieses Einschleusen von eigenem Code nennt man SQL Injection.

Was kann man tun um eine SQL Injection zu vermeiden?

Zuerst sollte man Prüfen ob man wirklich das bekommen hat was man ertwartet hat. So macht es Sinn zu prüfen ob man wirklich nur Zahlen bekommen hat, oder auch ob man wirklich nur bestimmte Einträge abfragt. Diese Positivlisten Methode stößt aber häufig an ihre Grenzen weil man nicht immer vorher wissen kann was der User so eingeben wird.

Daher kann man eine zweite Methode benutzen: Die Negativlisten Methode. Mit ihr kann man gewisse Wörter die auch SQL Befehle sind außschliesen, sollte die Negativ Liste mal greifen so kann man das Ausführen der Query verweigern. Diese Methode hat jedoch auch ihre Nachteile, so könnten richtige Eingaben zurückgewiesen werden weil sie einer nicht erlaubten Eingabe gleichen.

Wegen den Nachteilen der beiden bereits vorgestellten Methoden muss man sich häufig auf diese Funktion verlassen: mysql_real_escape_string(). Sie Maskiert alle Zeichen mit denen man aus den Anführungszeichen ausbrechen kann, sodass eine SQL Injection eigentlich unmöglich werden sollte. Man sollte sich aber möglichst selten nur auf sie verlassen sondern sollte sie auch möglichst immer mit den beiden anderen Methoden zusammen benutzen. Nur wenn man nicht weiß ob die beiden anderen Methoden vllt. falsch anbeißen könnten sollte man mysql_real_escape_string() benutzen.

Häufig wird auch die Funktion addslashes() benutzt um den Effekt von mysql_real_escape_string() zu bekommen. Bei der nicht sachgemäßen Benutzung treten dabei aber Fehler auf die dafür sorgen das ein mehrfaches Maskieren vorgenommen wird.


Das hier gegebene Beispiel für SQL Injections funktioniert in PHP nicht, aufgrund einer Beschränkung von mysql_query. Dies ist aber auch beabsichtigt um Missbrauch zu verhindern.
Aktionen
Login
Suche
Partner
Statistics