Nur anschauen:
(Quelle: https://xkcd.com/327/ )
Was macht diese SQL:
Robert'); DROP TABLE STUDENTS; --
Ich kenne beide '
und bin --
für Kommentare, aber wird das Wort DROP
nicht auch kommentiert, da es Teil derselben Zeile ist?
security
validation
sql-injection
Blankman
quelle
quelle
'
ist nicht für Kommentare . Selbst wenn dies der Fall wäre, steht kein Leerzeichen davor, sodass nur die vorhergehende Zeichenfolge beendet werden kann.Antworten:
Es lässt den Schülertisch fallen.
Der ursprüngliche Code im Schulprogramm sieht wahrscheinlich so aus
Dies ist die naive Methode zum Hinzufügen von Texteingaben zu einer Abfrage und , wie Sie sehen werden, sehr schlecht .
Nachdem die Werte aus dem Vornamen, dem zweiten Vornamen-Textfeld FNMName.Text (das ist
Robert'); DROP TABLE STUDENTS; --
) und dem Nachnamen-Textfeld LName.Text (nennen wir esDerper
) mit dem Rest der Abfrage verknüpft sind, sind das Ergebnis nun tatsächlich zwei durch das getrennt Anweisungsabschluss (Semikolon). Die zweite Abfrage wurde in die erste eingefügt . Wenn der Code diese Abfrage für die Datenbank ausführt, sieht sie folgendermaßen auswas im Klartext grob die beiden Abfragen übersetzt:
und
Alles nach der zweiten Abfrage wird als Kommentar markiert :
--', 'Derper')
Das
'
im Namen des Schülers ist kein Kommentar, sondern das abschließende Zeichenfolgenbegrenzer . Da der Name des Schülers eine Zeichenfolge ist, wird er syntaktisch benötigt, um die hypothetische Abfrage abzuschließen. Injection-Angriffe funktionieren nur, wenn die von ihnen injizierte SQL-Abfrage zu gültigem SQL führt .Herausgegeben wieder nach dan04 ‚s klugen Kommentar
quelle
INSERT
wäre, wäre die Klammer sinnvoller. Es würde auch erklären, warum die Datenbankverbindung nicht schreibgeschützt ist.INSERT
. Wenn man rückwärts denkt,SELECT
würde das sowieso nicht laufen, da das Einfügen der kleinen Bobby-Tische in die Tabelle die Tabelle bereits fallen gelassen hätte.Students
mehr als nur eine Spalte erwartet wird (die ursprüngliche / korrekte Anweisung enthält zwei Spalten). Das Vorhandensein der zweiten Spalte ist jedoch hilfreich, um zu zeigen, warum Kommentare erforderlich sind. und da man Bobbys Namen nicht ändern kann, ist es wahrscheinlich am besten, so wie er ist mit wenig mehr als dieser Beobachtung als Fußnote zu belassen.Angenommen, der Name wurde in einer Variablen verwendet
$Name
.Anschließend führen Sie diese Abfrage aus :
Der Code platziert fälschlicherweise alles, was der Benutzer als Variable angegeben hat.
Sie wollten, dass SQL :
Aber ein kluger Benutzer kann liefern, was er will:
Was Sie bekommen, ist:
Der
--
einzige kommentiert den Rest der Zeile.quelle
Wie alle anderen bereits betont haben,
');
schließt das die ursprüngliche Aussage und dann folgt eine zweite Aussage. Die meisten Frameworks, einschließlich Sprachen wie PHP, verfügen derzeit über Standardsicherheitseinstellungen, die nicht mehrere Anweisungen in einer SQL-Zeichenfolge zulassen. In PHP können Sie beispielsweise mit dermysqli_multi_query
Funktion nur mehrere Anweisungen in einer SQL-Zeichenfolge ausführen .Sie können jedoch eine vorhandene SQL-Anweisung über SQL Injection bearbeiten, ohne eine zweite Anweisung hinzufügen zu müssen. Angenommen, Sie haben ein Anmeldesystem, das einen Benutzernamen und ein Passwort mit dieser einfachen Auswahl überprüft:
Wenn Sie
peter
als Benutzernamen undsecret
als Kennwort angeben, sieht die resultierende SQL-Zeichenfolge folgendermaßen aus:Alles ist gut. Stellen Sie sich nun vor, Sie geben diese Zeichenfolge als Kennwort an:
Dann wäre die resultierende SQL-Zeichenfolge folgende:
Auf diese Weise können Sie sich bei jedem Konto anmelden, ohne das Kennwort zu kennen. Sie müssen also nicht in der Lage sein, zwei Anweisungen zu verwenden, um SQL-Injection zu verwenden, obwohl Sie destruktivere Dinge tun können, wenn Sie mehrere Anweisungen bereitstellen können.
quelle
Nein,
'
ist kein Kommentar in SQL, sondern ein Trennzeichen.Mama vermutete, dass der Datenbankprogrammierer eine Anfrage gestellt hatte, die wie folgt aussah:
(zum Beispiel) um den neuen Schüler hinzuzufügen, bei dem der
$xxx
variable Inhalt direkt aus einem HTML-Formular entnommen wurde, ohne das Format zu überprüfen oder Sonderzeichen zu umgehen.Wenn also das Datenbankprogramm
$firstName
enthältRobert'); DROP TABLE students; --
, wird die folgende Anforderung direkt in der Datenbank ausgeführt:dh. Die Anweisung insert wird vorzeitig beendet, der vom Cracker gewünschte schädliche Code ausgeführt und der verbleibende Code auskommentiert.
Mmmm, ich bin zu langsam, ich sehe schon 8 Antworten vor mir in der orangefarbenen Band ... :-) Ein beliebtes Thema, wie es scheint.
quelle
TL; DR
Dadurch wird die Schülertabelle gelöscht (gelöscht).
( Alle Codebeispiele in dieser Antwort wurden auf einem PostgreSQL 9.1.2-Datenbankserver ausgeführt. )
Um zu verdeutlichen, was passiert, versuchen wir dies mit einer einfachen Tabelle, die nur das Namensfeld enthält, und fügen eine einzelne Zeile hinzu:
Angenommen, die Anwendung verwendet das folgende SQL, um Daten in die Tabelle einzufügen:
Ersetzen Sie
foobar
durch den tatsächlichen Namen des Schülers. Ein normaler Einfügevorgang würde folgendermaßen aussehen:Wenn wir die Tabelle abfragen, erhalten wir Folgendes:
Was passiert, wenn wir den Namen von Little Bobby Tables in die Tabelle einfügen?
Die SQL-Injection ist hier das Ergebnis des Namens des Schülers, der die Anweisung beendet und einen separaten
DROP TABLE
Befehl enthält. Die beiden Striche am Ende der Eingabe sollen alle verbleibenden Codes auskommentieren, die sonst einen Fehler verursachen würden. Die letzte Zeile der Ausgabe bestätigt, dass der Datenbankserver die Tabelle gelöscht hat.Es ist wichtig zu beachten, dass
INSERT
die Anwendung während des Vorgangs die Eingabe nicht auf Sonderzeichen überprüft und daher die Eingabe beliebiger Eingaben in den SQL-Befehl ermöglicht. Dies bedeutet, dass ein böswilliger Benutzer in ein Feld, das normalerweise für Benutzereingaben vorgesehen ist, spezielle Symbole wie Anführungszeichen und beliebigen SQL-Code einfügen kann, um das Datenbanksystem zur Ausführung zu veranlassen, daher SQL- Injection .Das Ergebnis?
SQL Injection ist das Datenbankäquivalent einer Sicherheitsanfälligkeit bezüglich der Ausführung von beliebigem Remotecode in einem Betriebssystem oder einer Anwendung. Die möglichen Auswirkungen eines erfolgreichen SQL-Injection-Angriffs sind nicht zu unterschätzen. Je nach Datenbanksystem und Anwendungskonfiguration kann ein Angreifer Datenverluste verursachen (wie in diesem Fall), unbefugten Zugriff auf Daten erhalten oder sogar ausführen beliebiger Code auf dem Host-Computer selbst.
Wie im XKCD-Comic erwähnt, besteht eine Möglichkeit zum Schutz vor SQL-Injection-Angriffen darin, Datenbankeingaben zu bereinigen, z. B. indem Escapezeichen maskiert werden, damit sie den zugrunde liegenden SQL-Befehl nicht ändern und daher keinen beliebigen SQL-Code ausführen können. Wenn Sie parametrisierte Abfragen verwenden, z. B.
SqlParameter
in ADO.NET, wird die Eingabe mindestens automatisch bereinigt, um eine SQL-Injektion zu verhindern.Das Bereinigen von Eingaben auf Anwendungsebene kann jedoch fortgeschrittenere SQL-Injektionstechniken nicht stoppen. Beispielsweise gibt es Möglichkeiten, die
mysql_real_escape_string
PHP-Funktion zu umgehen . Für zusätzlichen Schutz unterstützen viele Datenbanksysteme vorbereitete Anweisungen . Bei ordnungsgemäßer Implementierung im Backend können vorbereitete Anweisungen die SQL-Injection unmöglich machen, indem Dateneingaben als semantisch vom Rest des Befehls getrennt behandelt werden.quelle
Angenommen, Sie haben naiv eine Schülererstellungsmethode wie diese geschrieben:
Und jemand gibt den Namen ein
Robert'); DROP TABLE STUDENTS; --
Was in der Datenbank ausgeführt wird, ist diese Abfrage:
Das Semikolon beendet den Einfügebefehl und startet einen anderen. the - kommentiert den Rest der Zeile aus. Der Befehl DROP TABLE wird ausgeführt ...
Aus diesem Grund sind Bindungsparameter eine gute Sache.
quelle
Ein einfaches Anführungszeichen ist der Anfang und das Ende einer Zeichenfolge. Ein Semikolon ist das Ende einer Anweisung. Wenn sie also eine Auswahl wie diese treffen würden:
Das SQL würde werden:
Auf einigen Systemen wird das
select
zuerst ausgeführt, gefolgt von derdrop
Anweisung! Die Meldung lautet: VERBINDEN SIE KEINE WERTE IN IHR SQL. Verwenden Sie stattdessen Parameter!quelle
Das
');
beendet die Abfrage, es startet keinen Kommentar. Dann wird die Schülertabelle gelöscht und der Rest der Abfrage kommentiert, die ausgeführt werden sollte.quelle
Der Verfasser der Datenbank hat wahrscheinlich eine
Wenn student_name angegeben ist, führt dies die Auswahl mit dem Namen "Robert" durch und löscht dann die Tabelle. Der Teil "-" ändert den Rest der angegebenen Abfrage in einen Kommentar.
quelle
In diesem Fall ist 'kein Kommentarzeichen. Es wird verwendet, um Zeichenfolgenliterale abzugrenzen. Der Comiczeichner setzt auf die Idee, dass die betreffende Schule irgendwo ein dynamisches SQL hat, das ungefähr so aussieht:
Jetzt beendet das Zeichen 'das Zeichenfolgenliteral, bevor der Programmierer es erwartet hat. Kombiniert mit dem; Um die Anweisung zu beenden, kann ein Angreifer nun beliebiges SQL hinzufügen. Der - Kommentar am Ende soll sicherstellen, dass die verbleibende SQL in der ursprünglichen Anweisung die Kompilierung der Abfrage auf dem Server nicht verhindert.
FWIW, ich denke auch das Comic in Frage ein wichtiges Detail falsch ist: Wenn Sie denken über desinfizierende Ihre Datenbank - Eingänge, wie der Comic schon sagt, du bist immer noch etwas falsch gemacht. Stattdessen sollten Sie über die Quarantäne Ihrer Datenbankeingaben nachdenken. Der richtige Weg, dies zu tun, sind parametrisierte Abfragen.
quelle
Das
'
Zeichen in SQL wird für Zeichenfolgenkonstanten verwendet. In diesem Fall wird es zum Beenden der Zeichenfolgenkonstante und nicht zum Kommentieren verwendet.quelle
So funktioniert es: Nehmen wir an, der Administrator sucht nach Aufzeichnungen über Schüler
Da das Administratorkonto über hohe Berechtigungen verfügt, ist das Löschen der Tabelle aus diesem Konto möglich.
Der Code zum Abrufen des Benutzernamens aus der Anforderung lautet
Jetzt wäre die Abfrage ungefähr so (um die Schülertabelle zu durchsuchen)
Die resultierende Abfrage wird
Da die Benutzereingabe nicht bereinigt ist, wird die obige Abfrage in zwei Teile zerlegt
Der doppelte Bindestrich (-) kommentiert nur den verbleibenden Teil der Abfrage aus.
Dies ist gefährlich, da die Kennwortauthentifizierung, falls vorhanden, ungültig werden kann
Der erste führt die normale Suche durch.
Der zweite löscht den Tischschüler, wenn das Konto über ausreichende Berechtigungen verfügt (im Allgemeinen führt das Schuladministratorkonto eine solche Abfrage aus und verfügt über die oben genannten Berechtigungen).
quelle
SELECT* FROM sutdents ...
- Du hast ein "s" vergessen. Das ist es, was du fallen lässt.DROP TABLE STUDENTS;
Sie müssen keine Formulardaten eingeben, um eine SQL-Injection durchzuführen.
Niemand hat zuvor darauf hingewiesen, so dass ich einige von Ihnen alarmieren könnte.
Meistens werden wir versuchen, Formulareingaben zu patchen. Dies ist jedoch nicht der einzige Ort, an dem Sie mit SQL-Injection angegriffen werden können. Sie können sehr einfache Angriffe mit URLs ausführen, die Daten über eine GET-Anforderung senden. Betrachten Sie das folgende Beispiel:
Ihre URL würde http://yoursite.com/show?id=1 aussehen
Jetzt könnte jemand so etwas versuchen
Versuchen Sie, table_name durch den echten Tabellennamen zu ersetzen. Wenn er Ihren Tischnamen richtig macht, würden sie Ihren Tisch leeren! (Es ist sehr einfach, diese URL mit einem einfachen Skript zu erzwingen.)
Ihre Anfrage würde ungefähr so aussehen ...
Beispiel für PHP-anfälligen Code mit PDO:
Lösung - Verwenden Sie die Methoden PDO prepare () & bindParam ():
quelle