it-swarm.com.de

Bereinigungseingabe für parametrisierte Abfragen

Wenn ich überall vollständig parametrisierte Abfragen verwende, ist es dann immer noch notwendig und/oder sicherheitsrelevant, Eingaben irgendwie zu bereinigen? Z.B. Überprüfen Sie, ob E-Mail-Adressen gültig sind, bevor Sie eine parametrisierte Abfrage an die Datenbank senden oder bestimmte Sonderzeichen aus dem Text herausfiltern.

Ich denke an harmlose, aber nicht so ausgereifte Tools von Drittanbietern (möglicherweise selbst geschriebene Skripte des Administrators oder einige ausgefallene CrystalReports, die von einem Nicht-Techniker erstellt wurden), die versuchen, nicht bereinigte Daten aus unserer Datenbank zu verwenden.

Im Moment haben wir volle Unicode-Unterstützung für SQL Server (MySQL scheint Probleme mit Emojis zu haben). Ich bin mir nicht sicher, wie ich Sicherheitsrisiken herausfiltern kann, ohne diese Eigenschaft zu verlieren.

16
Alexander

Nein, es ist nicht notwendig. Aber bitte lesen Sie weiter.

Input Desinfektion ist ein schrecklicher Begriff, der vorgibt, Sie könnten mit einem Zauberstab auf Daten winken und sie zu "sicheren Daten" machen. Das Problem ist, dass sich die Definition von "sicher" ändert, wenn die Daten von verschiedenen Softwareteilen interpretiert werden.

Daten, die möglicherweise sicher in eine SQL-Abfrage eingebettet werden können, sind möglicherweise nicht sicher für die Einbettung in HTML. Oder JSON. Oder Shell-Befehle. Oder CSV. Das Entfernen (oder völlige Ablehnen) von Werten, damit sie sicher in all diese Kontexte (und viele andere) eingebettet werden können, ist zu restriktiv.

Also, was sollten wir tun? Stellen Sie sicher, dass die Daten niemals Schaden anrichten können.

Der beste Weg, dies zu erreichen, besteht darin, eine Interpretation der Daten zu vermeiden. Parametrisierte SQL-Abfragen sind ein hervorragendes Beispiel dafür. Die Parameter werden niemals als SQL interpretiert, sondern einfach als Daten in die Datenbank gestellt.

In vielen anderen Situationen müssen die Daten noch in andere Formate eingebettet werden, z. B. HTML. In diesem Fall sollten die Daten für diese bestimmte Sprache zum Zeitpunkt der Einbettung maskiert werden. Um XSS zu verhindern, werden Daten zum Zeitpunkt der Anzeige mit HTML-Escapezeichen versehen. Nicht zur Eingabezeit. Gleiches gilt für andere Einbettungssituationen.

Sollen wir also alles, was wir bekommen, direkt an die Datenbank übergeben?

Könnte sein. Es hängt davon ab, ob.

Es gibt definitiv Dinge, die Sie über Benutzereingaben überprüfen können, aber dies ist stark kontextabhängig. Da die Desinfektion schlecht definiert und missbraucht wird, nenne ich dies lieber Validierung.

  • Wenn beispielsweise ein Feld eine Ganzzahl sein soll, können Sie dieses Feld auf jeden Fall überprüfen, um sicherzustellen, dass es eine Ganzzahl (oder möglicherweise NULL) enthält.
  • Sie können sicherlich eine Validierung für E-Mail-Felder durchführen (obwohl einige Leute argumentieren, dass Sie nicht viel tun können, außer auf das Vorhandensein eines @ Zu prüfen, und sie haben einen guten Punkt).
  • Sie können Kommentare mit einer minimalen und maximalen Länge verlangen.
  • Sie sollten wahrscheinlich überprüfen, ob eine Zeichenfolge nur gültige Zeichen für ihre Codierung enthält (z. B. keine ungültigen UTF-8-Sequenzen).
  • Sie können einen Benutzernamen auf bestimmte Zeichen beschränken, wenn dies für Ihre Benutzerbasis sinnvoll ist.
  • Eine Mindestlänge für Passwörter ist natürlich unglaublich häufig.

Wie Sie sehen können, sind diese Überprüfungen sehr kontextabhängig. Und alle sollen dazu beitragen, die Wahrscheinlichkeit zu erhöhen, dass Sie sinnvolle Daten erhalten. Sie sollen Ihre Anwendung nicht vor böswilligen Eingaben (SQL-Injection, XSS, Command-Injection usw.) schützen, da dies nicht der richtige Ort ist.

Benutzer sollten die Möglichkeit haben, '; DROP TABLE users; -- Einzugeben, ohne dass ihr Beitrag abgelehnt oder in \'; DROP TABLE users; -- Verstümmelt wird. Beachten Sie, dass ich solche "böswilligen" Inhalte in sec.SE aufnehmen kann!

Um Ihre ursprüngliche Frage zu beantworten:

... ist es immer noch notwendig und/oder sicherheitsrelevant, Eingaben irgendwie zu bereinigen?

Nein ist es nicht. Bitte maskieren Sie die Daten jedoch ordnungsgemäß, bevor Sie sie ausgeben. Berücksichtigen Sie gegebenenfalls Validierungen.

Ich denke an harmlose, aber nicht so ausgereifte Tools von Drittanbietern (möglicherweise selbst geschriebene Skripte des Administrators oder einige ausgefallene CrystalReports, die von einem Nicht-Techniker erstellt wurden), die versuchen, nicht bereinigte Daten aus unserer Datenbank zu verwenden.

Escape oder filtern Sie dann die Daten, bevor Sie sie an diese Tools ausgeben, aber entstellen Sie keine Daten in Ihrer Datenbank.

Aber wirklich, diese Skripte sollten repariert oder aus Sicherheitsgründen neu geschrieben werden.

(MySQL scheint Probleme mit Emojis zu haben)

Wenig off-topic, aber schauen Sie sich den Zeichensatz utfmb4 Für MySQL an;)

17
marcelm

Wenn ich überall vollständig parametrisierte Abfragen verwende, ist es dann immer noch notwendig und/oder sicherheitsrelevant, Eingaben irgendwie zu bereinigen?

Ja. Es ist immer eine gute Idee, die Eingabe zu bereinigen, bevor Sie sie an die Datenbank senden.

Parametrisierte Abfragen schützen Sie möglicherweise vor SQL-Injection-Angriffen, erweisen sich jedoch bei gespeicherten XSS-Angriffen möglicherweise nicht als vorteilhaft. Wenn ein Benutzer einen schädlichen Javascript-Code in Ihr Formular sendet und Sie ihn erfolgreich in Ihrer Datenbank speichern und dasselbe Feld an anderer Stelle anzeigen, wird das schädliche Skript möglicherweise im Browser des Opfers ausgeführt.

Es ist immer eine gute Idee, die Eingabe zu bereinigen, bevor Sie sie weiterleiten, und die Ausgabe zu bereinigen, bevor Sie sie an den Browser des Clients senden.

BEARBEITEN: Wie in den Kommentaren erwähnt, unterscheidet sich die Bereinigung von der Codierung/Escape-Werte. Desinfektion bedeutete hier, dass die Eingaben für einige grundlegende Überprüfungen validiert werden können, bevor sie an die Datenbank (oder eine weitere Schicht) weitergeleitet werden. Beispielsweise kann ein Feld, das eine E-Mail-Adresse erwartet, für eine gültige E-Mail-Adresse validiert werden, ein Feld für das Alter kann nur für eine Ganzzahl validiert werden usw. Reguläre Ausdrücke erweisen sich hier als immense Hilfe. Es ist zu beachten, dass diese Überprüfungen sowohl im Front-End (clientseitig) als auch im Back-End durchgeführt werden sollten.

Bei Feldern, die Rich Text erwarten, können Sie Content Security Policy auf Seiten implementieren, auf denen die Benutzereingaben angezeigt werden. Sie können auch einen HTML-Bereiniger verwenden, um die Benutzereingaben zu bereinigen.

8
pri

Ja, Sie sollten Eingabedaten immer bereinigen. Bei der Hygiene geht es nicht nur darum, Sie vor Injektionen zu schützen, sondern auch darum, Typen, eingeschränkte Werte (Aufzählungen), Bereiche usw. zu überprüfen. Ein Angreifer ist möglicherweise nicht in der Lage, Ihre SQL zu manipulieren, kann jedoch im Rest des Jahres zu unerwünschtem Verhalten führen Ihre Bewerbung.

Wenn ein Angreifer beispielsweise einen Aufzählungswert ändert, kann er dann das System manipulieren? Haben sie gerade eine Rolle, einen Benutzertyp usw. geändert? Alternativ können sie einen Wert eingeben, der größer ist als in Ihrem Schema oder im Datentyp (Byte v int32, int64) akzeptiert werden kann. Dies kann dazu führen, dass die Anwendung abstürzt, wodurch Informationen verfügbar gemacht werden oder verwaiste Daten geändert (nicht verarbeitet) werden.

3
JonnySchnittger