Hi
also es geht darum, dass bei direkter Verwendung von externen Werten (Benutzereingaben usw.) der Benutzer etc. hergehen kann und die Werte gezielt so wählen, dass die DB durcheinanderkommt, was jetzt ein Wert und was der Befehl selbst ist. Bei Prep.Statements gibt man den Befehl und die Werte komplett getrennt zur DB, statt sie zuerst zusammenzusetzen, daher kann die DB auch nicht durcheiannderkommen. Das wurde ja schon ausreichend gesagt.
Drei Punkte dazu aber noch:
a) "Falsche" Werte müssen gar nicht die Absicht haben, etwas blödes zu machen. Angenommen man hat in purem SQL folgendes Insert:
Code:
#Für Michael Jackson
INSERT INTO personen(name) VALUES("Michael Jackson");
Die Anführungszeichen hier markieren Beginn und Ende des Werts, der Rest ist SQL.
Sowas kann man natürlich nicht machen, da sich die DB dann beschweren wird.
Code:
#Für Michael Jackson
INSERT INTO personen(name) VALUES("Michael "Jacks"on"""""""""""");
Und wenn man einen leicht anderen Wert einfügen will:
Code:
#Für Michael Jackson, der "King of Pop"
INSERT INTO personen(name) VALUES("Michael Jackson, der "King of Pop"");
Und schon hat man eine falsche Anweisung - vor King ist der Wert für die DB schon wieder aus, Kinf of Pop ist kein Sql, und danach die zwei "" helfen auch nicht mehr.
Um das korrekt zu machen müsste man sowas tun:
Code:
#Für Michael Jackson, der "King of Pop"
INSERT INTO personen(name) VALUES("Michael Jackson, der \"King of Pop\"");
Also ein \ vor den " die nicht als Stringgrenzen gedacht sind, dann gehts (die \ sind nach dem Einfügen nicht mehr im Text, die sind nur Markierer für die DB).
...und wenn man das jetzt aus PHP aufruft, mit einem namen den der Benutzer eingegeben hat
Code:
query('INSERT INTO personen(name) VALUES("$name");');
muss man eben entweder dafür sorgen, dass zB. alle " in $name zuerst \" werden usw. (es gibt einige problematische Zeichen, die man so maskieren muss), oder Prepared Statements verwenden.
Wenn nicht, dann kann es zu solchen unabsichtlichen Problemen kommen, UND Benutzer können mit gezielten Werten natürlich auch gezielt die SQL-Anweisung verändern.
b) Welche Werten (von wo) kann man nicht vertrauen?
Idealerweise "allen", die nicht im (PHP-)Programm selbst erzeugt werden. Dinge die der Benutzer zB. in ein Formular eingibt ist relativ klar. Nicht so klar sind manchen Leuten, dass auch zB. folgende Sachen problematisch sein können: Werte, die man aus der DB abgefragt hat (die zuerst also schon dort waren), wenn sie ursprünglich Benutzereingaben etc. waren. Cookies. Eine Liste von Dateinamen in einem ordner am eigenen Server, die man sich automatisch zusammenstellt, wenn es Uploads von Benutzern sind. usw.usw.
c) Was kann man mit Sql-Injections schlimmstenfalls anrichten?
Hängt zwar sehr von der originalen Abfrage, DB-Einstellungen, usw. ab, und auch was das PHP-Programm mit Abfrageergebnissen machen, aber:
Alles in der DB nach Belieben ändern, ergänzen, löschen; PHP-Code mit falschen Abfrageergebnissen beliebig verwirren, und wenn der Benutzer bestimmte Abfrageergebnisse irgendwo auch sehen kann dann den gesamten DB-Inhalt anschauen.