2010-06-14 14 views
10

Das Skript ist in PHP und als DB verwende ich MySQL. Hier ist das Skript selbst.Ist diese Abfrage sicher vor SQL-Injektion?

$unsafe_variable = $_GET["user-input"]; 
$sql=sprintf("INSERT INTO table (column) VALUES('%s')",$unsafe_variable); 
mysql_query($sql); 

Manche Leute sagen, dass, wenn der Benutzer ;DROP TABLE blah; Zeichenfolge an die Variable $ ordnet unsafe_variable es die Tabelle löscht.

Aber ich versuchte, dieses Beispiel

http://localhost/test.php?user-input=DROP%20TABLE%20my_table 

Aber es hat nicht die Tabelle löscht, sondern eine neue Zeile (;DROP TABLE blah;) in der Tabelle eingefügt.

Kann mir jemand erklären, wie es möglich ist, dieses Skript mit SQL-Injektionen anzugreifen?

+3

'mysqli' oder' PDO' und ihre vorbereiteten Anweisungen würde sei eine bessere Wahl. – Powerlord

+0

Vielen Dank für alle Teilnehmer der Frage. Ich habe wirklich gemerkt, dass wir mit 'sprintf' nicht sicher sein können, dass unsere Abfrage vor ** sql-injections ** sicher ist. Für dieses spezielle Beispiel konnten weder ich noch die Teilnehmer den Weg zur Ausführung von sql-injection darstellen. Aber ich habe ein gutes SQL-Beispiel gefunden, wo wir sql-injection ausführen können, auch wenn wir 'sprintf' verwenden. Das SQL-Beispiel kann [hier] (http://php.net/manual/en/function.mysql-real-escape-string.php "PHP Online Manual") gefunden werden. Siehe Abschnitt "Beispiel # 2 Ein Beispiel für einen SQL Injection Attack" – Bakhtiyor

Antwort

13

Diese spezielle Injektion würde nicht funktionieren, da die mysql_query-Funktion von PHP nur eine Abfrage pro Aufruf erlaubt. Jedoch kann die folgende funktionieren, wenn column einen primären oder eindeutige Schlüssel hat:

$unsafe_variable = "admin') ON DUPLICATE KEY UPDATE password=MD5(CONCAT('knownsalt', 'newpassword'))#"; 

besser zu nutzen, um die langatmige mysql_real_escape_string Funktion:

$sql=sprintf("INSERT INTO table (column) VALUES(%s)", 
      mysql_real_escape_string($unsafe_variable)); 
mysql_query($sql); 
4

mysql_query() ermöglicht nicht die Ausführung mehrerer Abfragen in einer Funktion. Sie können also nicht INSERT und dann die Tabelle ablegen. Aber darauf sollten Sie sich nicht als "Sicherheit" verlassen. Verwenden Sie stattdessen parametrisierte Abfragen. Schauen Sie sich die PDO Bibliothek von PHP an.

Sie könnten jedoch so gut wie alles andere ändern, wie zum Beispiel das AUSWAHL eines Passwortfeldes aus einer anderen Tabelle als Unterabfrage in diese Tabelle, damit sie den Hash sehen können.

+0

http://php.net/manual/en/function.mysql-query.php –

+0

Gibt es einen Grund für einen Downvote? Vorbereitete Anweisungen sind im Allgemeinen sicherer als "mysql_real_escape_string". –

1

Nö, sprintf entkommen nicht den Inhalt:

$unsafe_variable = mysql_real_escape_string($_GET["user-input"]); 
$sql=sprintf("INSERT INTO table (column) VALUES('%s')",$unsafe_variable); 
mysql_query($sql); 
1
mysql_real_escape_string($unsafe_variable) 
3

Während mysql_query nur eine Abfrage ermöglicht im Allgemeinen auszuführen, diese Abfrage nicht sicher ist. Ein Beispiel für eine gefährliche Eingabe, die Ihre Abfrage ausnutzen würde, ist:

'); DROP TABLE my_table; -- 

Die '); zu Beginn Ihre Anfrage schließen und einen leeren Wert einfügen, sondern für zusätzliche Abfragen können nach dem INSERT ausgeführt werden. Dann, nach dem Löschen einer Tabelle, markiert die -- am Ende alles andere folgende (dh den Rest Ihrer Anfrage) als Kommentar.

Verwenden Sie mysql_real_escape_string, um Eingaben für die Verwendung in einer Abfrage sicher vorzubereiten.

+0

Willst du sagen, dass wenn ich dieses Skript [http: //authoringtool/test.php? User-input = ');% 20DROP% 20TABLE% 20my_table2;% 20--] es my_table2 aus meiner DB löschen? Wenn nicht, bitte geben Sie mir ein Beispiel dafür, wie es funktioniert, weil Ihr Beispiel my_table2 nicht gelöscht hat :) – Bakhtiyor

+1

Wie gesagt, 'mysql_query' unterstützt nicht die Ausführung mehrerer Abfragen, aber Sie sollten Ihre Abfrage immer noch sichern. –

1

Einige Leute sagen, dass, wenn Benutzer ordnet; DROP TABLE blah; String zu der Variablen $ unsafe_variable löscht die Tabelle.

Offensichtlich ist das nicht der Fall - aber wenn Sie nicht verstehen, warum, dann können Sie nicht sagen, ob Ihr Code sicher ist. Werden Sie hier jede Zeile posten, um zu überprüfen, ob sie sicher ist?

Ohne in eine lange Erklärung darüber zu gehen, was der oben genannte Code tut und wie man ihn kompromittieren kann (SQL-Injektion ist bereits an anderer Stelle sehr gut dokumentiert - versuchen Sie Google), sollten Sie IMMER sicherstellen, dass alle Daten Ihren PHP-Code verlassen in der richtigen Darstellung für wohin es geht.

Für eine MySQL-Datenbank, die bedeutet entweder:

1) die Ausgabe von mysql_real_escape_string verwenden (und stellen Sie sicher, dass Sie die richtige Ressource Griff zu bekommen)

oder

2) verwenden Parameterbindung.

Eine richtige Diskussion über Code-Injection-Angriffe könnte leicht mehrere hundert Seiten füllen - ein bisschen viel zu beantworten in einem S.O. Abfrage.

C.

0

Ich denke, das Beispiel, das Sie versuchen, brauchen würde http://localhost/test.php?user-input=';DROP%20TABLE%20my_table'

ist die '); schließt das values('%s Segment, und gibt dann einen neuen Befehl, drop table...

+0

Das funktioniert nicht. – Bakhtiyor

Verwandte Themen