Ich verstehe, dass Sie Benutzereingaben aus einem Formular NIEMALS vertrauen sollten, hauptsächlich aufgrund der Möglichkeit einer SQL-Injection.
Gilt dies jedoch auch für ein Formular, bei dem die einzige Eingabe von einem Dropdown (s) stammt (siehe unten)?
Ich speichere das $_POST['size']
in einer Sitzung, die dann auf der gesamten Site verwendet wird, um die verschiedenen Datenbanken abzufragen (mit einer mysqli
Select-Abfrage), und jede SQL-Injection würde sie definitiv beschädigen (möglicherweise löschen).
Es gibt keinen Bereich für eingegebene Benutzereingaben zum Abfragen der Datenbanken, nur Dropdown-Listen.
<form action="welcome.php" method="post">
<select name="size">
<option value="All">Select Size</option>
<option value="Large">Large</option>
<option value="Medium">Medium</option>
<option value="Small">Small</option>
</select>
<input type="submit">
</form>
php
mysql
mysqli
sql-injection
Lumpen
quelle
quelle
<select>
Eingabe zu übermitteln . In der Tat könnte sogar ein etwas technischer Benutzer zusätzliche Optionen über die Browserkonsole hinzufügen. Wenn Sie eine Array-Whitelist mit verfügbaren Werten führen und die Eingabe damit vergleichen, können Sie dies abschwächen (und Sie sollten dies tun, da dies unerwünschte Werte verhindert)Antworten:
Sie können etwas so Einfaches wie das folgende Beispiel tun, um sicherzustellen, dass die angegebene Größe Ihren Erwartungen entspricht.
Verwenden Sie dann mysqli_ *, wenn Sie eine Version von php> = 5.3.0 verwenden, die Sie sein sollten, um Ihr Ergebnis zu speichern. Bei korrekter Verwendung hilft dies bei der SQL-Injektion.
quelle
mysqli_real_escape_string
. Schließen Sie die Werte bei der Ausgabe auch ordnungsgemäß an (z. B. verwenden Sie htmlspecialchars () in einem HTML-Dokument).in_array
totrue
für einen strengen Vergleich festzulegen. Ich bin mir nicht sicher, was schief gehen könnte, aber ein loser Vergleich ist ziemlich eigenartig.Ja, Sie müssen sich davor schützen.
Lassen Sie mich Ihnen anhand der Firefox-Entwicklerkonsole zeigen, warum:
Wenn Sie diese Daten nicht bereinigen, wird Ihre Datenbank zerstört. (Dies ist möglicherweise keine vollständig gültige SQL-Anweisung, aber ich hoffe, ich habe meinen Standpunkt klargestellt.)
Nur weil Sie die verfügbaren Optionen in Ihrer Dropdown-Liste eingeschränkt haben, bedeutet dies nicht, dass Sie die Daten, die ich an Ihren Server senden kann, eingeschränkt haben.
Wenn Sie versucht haben, dies mithilfe des Verhaltens auf Ihrer Seite weiter einzuschränken, können Sie dieses Verhalten deaktivieren oder einfach eine benutzerdefinierte HTTP-Anforderung an Ihren Server schreiben, die diese Formularübermittlung ohnehin nachahmt. Genau dafür wird ein Tool namens curl verwendet, und ich denke, der Befehl zum Senden dieser SQL-Injection würde ungefähr so aussehen:
(Dies ist möglicherweise kein vollständig gültiger Curl-Befehl, aber ich hoffe, ich habe meinen Standpunkt klar zum Ausdruck gebracht.)
Also werde ich wiederholen:
NIEMALS Benutzereingaben vertrauen. Schützen Sie sich IMMER.
Gehen Sie nicht davon aus, dass Benutzereingaben jemals sicher sind. Es ist möglicherweise unsicher, selbst wenn es auf andere Weise als durch ein Formular ankommt. Nichts davon ist jemals vertrauenswürdig genug, um auf den Schutz vor SQL-Injection zu verzichten.
quelle
curl
. IMMER sanieren Eingangsserverseitige !curl
. Die Leute verstehen nicht, dass Sie eine HTTP-Anfrage von überall nach überall in einem beliebigen Format senden und Werte übergeben können. Es ist Sache des Servers, sicherzustellen, dass die Anfrage gültig ist, bevor Sie sie verarbeiten.Da diese Frage mit getaggt wurde SQL-InjektionHier ist eine Antwort zu dieser besonderen Art von Angriff:
Wie Sie in den Kommentaren erfahren haben, müssen Sie für jede einzelne Abfrage, die variable Daten enthält, ohne Ausnahmen vorbereitete Anweisungen verwenden .
Unabhängig von HTML-Inhalten!
Es ist wichtig zu verstehen, dass SQL-Abfragen unabhängig von externen Faktoren, sei es HTML-Eingabe oder irgendetwas anderem, richtig formatiert werden müssen .
Obwohl Sie die in anderen Antworten vorgeschlagene White-Listing-Funktion für die Eingabeüberprüfung verwenden können, sollte dies keine Auswirkungen auf SQL-bezogene Aktionen haben - sie müssen gleich bleiben, unabhängig davon, ob Sie die HTML-Eingabe validiert haben oder nicht. Dies bedeutet, dass Sie immer noch vorbereitete Anweisungen verwenden müssen, wenn Sie Variablen zur Abfrage hinzufügen.
Hier finden Sie eine ausführliche Erklärung, warum vorbereitete Anweisungen ein Muss sind und wie sie richtig verwendet werden und wo sie nicht anwendbar sind und was in einem solchen Fall zu tun ist: Per Anhalter durch den SQL Injection-Schutz
Auch diese Frage wurde mit getaggt Mysqli. Meistens aus Versehen, nehme ich an, aber trotzdem muss ich Sie warnen, dass rohes mysqli kein adäquater Ersatz für die alten mysq_ * -Funktionen ist . Einfach, weil es, wenn es im alten Stil verwendet wird, überhaupt keine Sicherheit bietet. Die Unterstützung für die vorbereiteten Anweisungen ist zwar schmerzhaft und mühsam, aber der durchschnittliche PHP-Benutzer kann sie überhaupt nicht mehr ausführen. Wenn also kein ORM oder eine Art Abstraktionsbibliothek verfügbar ist, ist PDO Ihre einzige Wahl.
quelle
random
?Ja.
Jeder kann alles für die Werte fälschen, die tatsächlich gesendet werden -
Um Validierungsmenüs zu validieren, können Sie einfach überprüfen, ob der Wert, mit dem Sie arbeiten, in der Dropdown-Liste enthalten ist. So etwas wäre der beste (am meisten paranoide) Weg:
quelle
Eine Möglichkeit, sich vor Benutzern zu schützen, die Ihre Dropdowns mithilfe der Konsole ändern, besteht darin, nur ganzzahlige Werte zu verwenden. Anschließend können Sie überprüfen, ob der POST-Wert eine Ganzzahl enthält, und diese bei Bedarf mithilfe eines Arrays in Text konvertieren. Z.B:
Dann können Sie
$size
Ihre Abfrage mit dem Wissen verwenden, dass sie immer nurFALSE
eine Ganzzahl enthält.quelle
filter_input
wenn nicht eine Überprüfung auf der Serverseite? Niemand kann etwas anderes als eine ganze Zahl posten.filter_input
Teil auch für die Validierung verwenden, da es sonst aus Sicherheitsgründen genauso nützlich ist wie eine Schokoladenteekanne.Die anderen Antworten decken bereits das ab, was Sie wissen müssen. Aber vielleicht hilft es, noch etwas zu klären:
Es gibt ZWEI DINGE, die Sie tun müssen:
1. Überprüfen Sie die Formulardaten.
Wie die Antwort von Jonathan Hobbs sehr deutlich zeigt, führt die Auswahl des HTML-Elements für die Formulareingabe zu keiner zuverlässigen Filterung für Sie.
Die Validierung erfolgt normalerweise so, dass die Daten nicht geändert werden, das Formular jedoch erneut angezeigt wird. Die Felder sind mit "Bitte korrigieren" gekennzeichnet.
Die meisten Frameworks und CMS verfügen über Formularersteller, die Sie bei dieser Aufgabe unterstützen. Und nicht nur das, sie helfen auch gegen CSRF (oder "XSRF"), eine andere Form des Angriffs.
2. Bereinigen / Escape-Variablen in SQL-Anweisungen.
.. oder lassen Sie vorbereitete Aussagen die Arbeit für Sie erledigen.
Wenn Sie eine (My) SQL-Anweisung mit vom Benutzer bereitgestellten oder nicht vom Benutzer bereitgestellten Variablen erstellen, müssen Sie diese Variablen maskieren und in Anführungszeichen setzen.
Im Allgemeinen sollte jede solche Variable, die Sie in eine MySQL-Anweisung einfügen, entweder eine Zeichenfolge sein oder etwas, das PHP zuverlässig in eine Zeichenfolge umwandeln kann, die MySQL verarbeiten kann. Wie Zahlen.
Für Zeichenfolgen müssen Sie dann eine von mehreren Methoden auswählen, um die Zeichenfolge zu umgehen. Das heißt, Sie müssen alle Zeichen ersetzen, die in MySQL Nebenwirkungen haben würden.
Wenn Sie es mit einer Zahl zu tun haben, können Sie das Escapezeichen und die Anführungszeichen weglassen (aus diesem Grund können Sie in den vorbereiteten Anweisungen einen Typ angeben).
Es ist wichtig darauf hinzuweisen, dass Sie die Variablen für die SQL-Anweisung und NICHT für die Datenbank selbst maskieren . Die Datenbank speichert die ursprüngliche Zeichenfolge, die Anweisung benötigt jedoch eine maskierte Version.
Was passiert, wenn Sie eines davon weglassen?
Wenn Sie keine Formularvalidierung verwenden , aber Ihre SQL-Eingabe bereinigen, werden möglicherweise alle Arten von schlechten Dingen auftreten, aber Sie werden keine SQL-Injection sehen! (*)
Erstens kann Ihre Bewerbung in einen Zustand versetzt werden, den Sie nicht geplant haben. Wenn Sie beispielsweise das Durchschnittsalter aller Benutzer berechnen möchten, aber ein Benutzer "aljkdfaqer" für das Alter angegeben hat, schlägt Ihre Berechnung fehl.
Zweitens kann es alle Arten von anderen Injektionsangriffen geben, die Sie berücksichtigen müssen: Beispielsweise könnte die Benutzereingabe Javascript oder anderes Material enthalten.
Es kann immer noch Probleme mit der Datenbank geben: ZB wenn ein Feld (Datenbanktabellenspalte) auf 255 Zeichen begrenzt ist und die Zeichenfolge länger ist. Oder wenn das Feld nur Zahlen akzeptiert und Sie versuchen, stattdessen eine nicht numerische Zeichenfolge zu speichern. Dies ist jedoch keine "Injektion", sondern nur ein "Absturz der Anwendung".
Aber selbst wenn Sie ein Freitextfeld haben, in dem Sie Eingaben ohne Validierung zulassen, können Sie diese einfach so in der Datenbank speichern, wenn Sie sie beim Aufrufen einer Datenbankanweisung ordnungsgemäß umgehen. Das Problem tritt auf, wenn Sie diese Zeichenfolge irgendwo verwenden möchten.
(*) oder das wäre etwas wirklich Exotisches.
Wenn Sie Variablen für SQL-Anweisungen nicht entkommen , aber die Formulareingabe validiert haben, können Sie immer noch sehen, dass schlechte Dinge passieren.
Erstens besteht das Risiko, dass beim Speichern und erneuten Laden von Daten in die Datenbank nicht mehr dieselben Daten "verloren gehen".
Zweitens kann dies zu ungültigen SQL-Anweisungen führen und somit Ihre Anwendung zum Absturz bringen. Wenn beispielsweise eine Variable ein Anführungszeichen oder ein doppeltes Anführungszeichen enthält, erhalten Sie je nach verwendetem Anführungszeichentyp eine ungültige MySQL-Anweisung.
Drittens kann es immer noch zu einer SQL-Injection kommen.
Wenn Ihre Benutzereingaben aus Formularen bereits gefiltert / validiert sind, kann eine absichtliche SQl-Injektion weniger wahrscheinlich werden, wenn Ihre Eingabe auf eine fest codierte Liste von Optionen reduziert wird oder wenn sie auf Zahlen beschränkt ist. Jede freie Texteingabe kann jedoch für die SQL-Injection verwendet werden, wenn Sie die Variablen in SQL-Anweisungen nicht ordnungsgemäß umgehen.
Und selbst wenn Sie überhaupt keine Formulareingabe haben, können Sie dennoch Zeichenfolgen aus allen Arten von Quellen haben: Aus dem Dateisystem lesen, aus dem Internet kratzen usw. Niemand kann garantieren, dass diese Zeichenfolgen sicher sind.
quelle
Ihr Webbrowser "weiß" nicht, dass er eine Seite von PHP empfängt. Alles, was er sieht, ist HTML. Und die http-Schicht weiß noch weniger. Sie müssen in der Lage sein, nahezu jede Art von Eingabe zu verarbeiten, die die http-Ebene überschreiten kann (zum Glück wird bei den meisten Eingabe-PHP bereits ein Fehler ausgegeben). Wenn Sie versuchen zu verhindern, dass böswillige Anfragen Ihre Datenbank durcheinander bringen, müssen Sie davon ausgehen, dass der Typ am anderen Ende weiß, was er tut, und dass er nicht auf das beschränkt ist, was Sie unter normalen Umständen in Ihrem Browser sehen können ( ganz zu schweigen davon, was Sie mit den Entwicklertools eines Browsers spielen können. Ja, Sie müssen alle Eingaben aus Ihrem Dropdown-Menü berücksichtigen, aber für die meisten Eingaben können Sie einen Fehler angeben.
quelle
Die Tatsache, dass Sie den Benutzer darauf beschränkt haben, nur Werte aus einer bestimmten Dropdown-Liste zu verwenden, ist irrelevant. Ein technischer Benutzer kann die an Ihren Server gesendete http-Anfrage erfassen, bevor er sein Netzwerk verlässt, sie mit einem Tool wie einem lokalen Proxyserver ändern und dann auf seinem Weg fortsetzen. Mithilfe der geänderten Anforderung können sie Parameterwerte senden, die nicht in der Dropdown-Liste angegeben sind. Entwickler müssen die Einstellung haben, dass Client-Einschränkungen oft bedeutungslos sind, da alles auf einem Client geändert werden kann. Die Serverüberprüfung ist an jedem einzelnen Punkt erforderlich, an dem Clientdaten eingegeben werden. Angreifer verlassen sich in diesem einzigen Aspekt auf die Naivität der Entwickler.
quelle
Verwenden Sie am besten eine parametrisierte Abfrage, um eine SQL-Injection zu vermeiden. In diesem Fall sieht die Abfrage folgendermaßen aus:
Wenn Sie eine Abfrage wie die oben genannte mit Text versehen, dessen Integrität nicht überprüft wurde (die Eingabe wird auf dem Server nicht überprüft) und der SQL-Injection-Code enthält, wird sie korrekt behandelt. Mit anderen Worten, die Anforderung führt dazu, dass in der Datenbankebene Folgendes passiert:
Dadurch werden bei der Rückgabe einfach 0 Ergebnisse ausgewählt, wodurch die Abfrage unwirksam wird und der Datenbank tatsächlich Schaden zufügt, ohne dass eine Whitelist, eine Überprüfungsprüfung oder andere Techniken erforderlich sind. Bitte beachten Sie, dass ein verantwortlicher Programmierer die Sicherheit in Schichten übernimmt und häufig zusätzlich zur Parametrisierung von Abfragen validiert. Es gibt jedoch kaum einen Grund, Ihre Abfragen aus Sicht der Leistung nicht zu parametrisieren, und die durch diese Vorgehensweise hinzugefügte Sicherheit ist ein guter Grund, sich mit parametrisierten Abfragen vertraut zu machen.
quelle
Was auch immer von Ihrem Formular gesendet wird, wird als Text über die Kabel an Ihren Server gesendet. Nichts hindert jemanden daran, einen Bot zu erstellen, der den Client nachahmt oder ihn von einem Terminal aus eingibt, wenn er möchte. Gehen Sie niemals davon aus, dass sich der Client, weil Sie ihn programmiert haben, so verhält, wie Sie es sich vorstellen. Das ist wirklich leicht zu fälschen.
Beispiel dafür, was passieren kann und wird, wenn Sie dem Kunden vertrauen.
quelle
Ein Hacker kann den Browser einschließlich der Überprüfung von Javascript-Formularen vollständig umgehen, indem er eine Anfrage über Telnet sendet. Natürlich wird er sich den Code Ihrer HTML-Seite ansehen, um die Feldnamen zu erhalten, die er verwenden muss, aber von da an ist alles für ihn erledigt. Sie müssen also alle auf dem Server übermittelten Werte überprüfen, als ob sie nicht von Ihrer HTML-Seite stammen.
quelle