Frage:
Input-Desinfektion vs. Output-Desinfektion
Todd Schwine
2015-07-30 06:34:55 UTC
view on stackexchange narkive permalink

In den Bits, nach denen ich gesucht habe, habe ich einige Leute gesehen, die als Wort Gottes erklärt haben, dass Sie nur Ausgaben und keine Eingaben bereinigen sollten. Warum? Wäre es nicht sicherer, beide Enden abzudecken?

Wie gesagt, dies ist eine Meinungsfrage, die einen Flammenkrieg auslösen könnte (und aus diesem Grund geschlossen werden könnte). Sie könnten [bearbeiten] (https://security.stackexchange.com/posts/95325/edit), um eher zu sagen: "Was sind die Vor- und Nachteile beider Ansätze?"
Ich würde gerne einen Verweis auf _anyone_ sehen, der besagt, dass Sie Eingaben nicht bereinigen sollten.
@gowenfawr Dafür gibt es Fälle; Unsere Sicherheitsabteilung ermutigt uns, unsere Desinfektion so nah wie möglich an der Ausgangsleitung zu platzieren (DB Call oder WTV), da dies die Codeüberprüfung erleichtert. Das Grundprinzip ist, dass es für sie einfacher ist, für DB-Aufrufe Strg + F zu drücken als für alle möglichen Eingabequellen.
@gowenfawr Es ist nicht so, dass Sie Eingaben nicht bereinigen sollten, sondern für die systeminterne Datenübertragung liegt der Schwerpunkt auf der Ausgabebereinigung (unter der Annahme, dass das OP Erfahrungen gesammelt hat).
Das heißt, Todd, könnten Sie dieser Frage einen Begriff von Umfang hinzufügen?
Könnten Sie näher erläutern, was Sie unter "Input-Desinfektion" und "Output-Desinfektion" verstehen?
** Bitte erläutern Sie: ** Wenn ich Daten (1) vom Benutzer in ein Formularfeld (2) eingegeben habe, die an die Serveranwendung gesendet wurden (3) an das Persistenz-Framework gesendet wurden (4) in den Tabellenspalten gespeichert und dann später (5) aus der Tabelle (6) lesen, die vom Anwendungsserver (7) gepackt und formatiert wurde, der dem Benutzer auf einer Webseite präsentiert wurde ... "Wo sehen Sie Eingabe / Ausgabe?"
@MikeOunsworth Mein Verständnis Ihres Szenarios ist, dass Sie Eingaben immer noch bereinigen. Ich sehe Ihr Szenario folgendermaßen: Zeile 24: Sanitize (); Zeile 25: Db.Execute (); Linie: w / e; Dies würde es zu einer Eingabesanierung machen, wie es im Eingabestream geschieht.
@FlorinCoada Ja, es ist immer noch die Eingabe _stream_, aber Sie lassen zu, dass die Roheingabe im Speicher gespeichert und möglicherweise von einem Parser verarbeitet wird, bevor sie bereinigt wird. Zeile 25: str = get_input (); Zeile 26: // ...; Zeile 150: Desinfizieren (str); Zeile 151: Db.Execute () `. Möglicherweise würden Sie es sowohl bei der Eingabe als auch bei der Ausgabe bereinigen, damit kein Risiko besteht, dass es einen der Bibliotheksaufrufe zwischen den Zeilen 26 bis 149 ausnutzt.
@MikeOunsworth An welchem ​​Punkt zwischen den Zeilen 26-149 wurde die Eingabe plötzlich zu einer Ausgabe? Es ist noch nicht einmal in die Datenbank gegangen ...
@Michael Ich hätte schreiben sollen 'Zeile 151: Db.Execute (str);' Aber ich denke, ich sehe die größere Verwirrung; Für mich ist "Ausgabe" eine beliebige Zeichenfolge, die meinen eigenen Quellcode hinterlässt, beispielsweise an einen Systemaufruf übergeben oder in eine Datei / Datenbank geschrieben wird. Aber ich nehme an, dass viele Leute diesen Eingang immer noch nennen würden, da er von einem Benutzer kam.
Fünf antworten:
#1
+30
saghaulor
2015-07-30 08:29:56 UTC
view on stackexchange narkive permalink

Wenn Sie Eingaben bereinigen, besteht die Gefahr, dass Sie die Daten so ändern, dass sie möglicherweise unbrauchbar werden. Daher wird die Bereinigung von Eingaben in Fällen vermieden, in denen die Art der Daten unbekannt ist. Zum Beispiel haben einige Sonderzeichen möglicherweise eine Bedeutung in den Daten, und wenn sie entfernt werden, bedeutet dies, dass diese Bedeutung zerstört wird.

Ein solches Szenario kann sein, dass Ihr System Daten speichert, die später in ein System eines Drittanbieters gezogen werden, und in diesem System haben diese Zeichen eine Bedeutung. Indem Sie sie entfernen, haben Sie die Daten erheblich verändert. Beispielsweise wird die Zeichenfolge möglicherweise als Schlüssel zum Nachschlagen eines Datensatzes im System eines Drittanbieters verwendet. Durch Entfernen des Symbols ändern Sie den Schlüssel so, dass der Datensatz nicht gefunden werden kann.

Die Eingabebereinigung kann verwendet werden Wenn diese Art der Daten bekannt ist und die Desinfektion die Daten ohnehin nicht beeinträchtigt.

Ihre Entscheidung, Eingabedaten zu bereinigen, ist teilweise eine Geschäftsentscheidung. Wird das System eines Drittanbieters von der Eingabe genau so abhängen, wie sie bereitgestellt wird? Wenn ja, ist es wahrscheinlich keine gute Idee. Möglicherweise können Sie die Erwartungen jedoch so gestalten, dass die Dritten verstehen, dass Sie Eingabedaten anhand eines bestimmten Kriteriums bereinigen, das Sie mit ihnen teilen.

Außerdem wissen Sie (fast) immer, welches Format Sie ausgeben. Entweder geben Sie "HTML" oder "Javascript" oder "Dateipfade" oder "SQL" usw. aus, und Sie können es in diesem Kontext bereinigen, da verschiedene Dinge in verschiedenen Kontexten sicher sind.
Ich stimme @MikeOunsworth zu. Wenn Sie die Daten ausgeben, kennen Sie den Anwendungsfall der Daten. Mit diesem Wissen können Sie die Ausgabedaten entsprechend sicher bereinigen.
Ich würde diese Ausgabecodierung anstelle von Desinfektion nennen.
#2
+13
RatboySTL
2015-07-30 18:00:20 UTC
view on stackexchange narkive permalink

Gee ... "Ausgabe bereinigen." Ich habe diesen Begriff noch nie gehört. Ich habe das getan, oh, ich weiß es nicht. Zumindest über ein Jahrzehnt. Sie "bereinigen Ihre Ausgabe nicht", sondern codieren sie für den richtigen Kontext innerhalb der Anwendung, die sie präsentiert. Sie codieren die Ausgabe für HTML, HTML-Attribut, URL, JavaScript ... Ich habe noch nie jemanden gesehen oder gehört, der behauptet, Sie "bereinigen" Ihre Ausgabe ... meinen Sie Leute im Sinne von Whitelisting oder Blacklisting Welche bestimmten Zeichenfolgen können beispielsweise über die Leitung an den Browser gesendet werden? Niemand macht das. Sie sollten es aus den oben genannten Gründen sowieso nicht tun - Sie wissen nicht, was die legitime Verwendung bestimmter Daten für eine bestimmte Anwendung sein kann ... einige Websites (wie zum Beispiel diese) müssen Ermöglicht das Hochladen von Code und das Rendern als Code im Anforderungs-Antwort-Lebenszyklus. Wie könnten Beispiele für Code jemals auf Code-Sharing-Sites ausgetauscht werden, wenn Sie beispielsweise die Verwendung eines Skript-Tags nicht zulassen?

Übrigens: "Sie können im Nachhinein niemals die Datenbank durchsuchen und sehen, wie Viele der Beiträge waren böswillig. " ist einfach nicht wahr. Es stehen Scrubber zur Verfügung, mit denen Sie eine Datenbank durchsuchen und schädlichen Code "scrubben" können. Ich weiß, ich habe es letztes Jahr für ein großes Finanzdienstleistungsunternehmen getan.

Ich denke, Sie haben es falsch verstanden. "Sie können niemals im Nachhinein durch die Datenbank gehen und sehen, wie viele der Beiträge böswillig waren." - Es wurde im Zusammenhang mit der Bereinigung des Inputs gesagt. In diesem Fall ist der böswillige Teil verschwunden. Nein, Sie können nicht zurückgehen und nach den ursprünglich böswilligen suchen.
+1, denn warum sollten Sie die Ausgabe bereinigen - Sie sind derjenige, der sie generiert hat, richtig?
#3
+8
Odalrick
2015-07-30 17:03:04 UTC
view on stackexchange narkive permalink

Sie wissen nicht, wie Daten bereinigt werden sollen, bis Sie sie ausgeben oder genauer verwenden.

In vielen Fällen scheint dies der Fall zu sein offensichtlich; In Ihrer Blogging-Engine möchten Sie Skript-Tags herausfiltern. Immer und immer löschen Sie sie einfach aus der Eingabe und denken nie wieder an sie.

In anderen Fällen ist es möglicherweise nicht so einfach. wenn dieselben Daten in unterschiedlichen Kontexten verwendet werden. "<" muss in HTML in "&lt;" maskiert werden und ist völlig harmlos, wenn es als Text exportiert wird.

Aber selbst wenn es einfach ist, verlieren Sie wichtige Daten, wenn Sie <script> aus Ihrer Eingabe entfernen. Sie können im Nachhinein niemals in der Datenbank nachsehen, wie viele der Beiträge böswillig waren.

Dann besteht die Möglichkeit, Zielpfosten zu verschieben: Jemand findet einen neuen Exploit, mit dem sich Ihr Filter nicht befasst. Plötzlich müssen Sie einen festen Filter erneut auf Ihre gesamte Datenbank anwenden. Was ist, wenn Ihr Fix einen falsch positiven Fehler enthält?

Aber selbst wenn Sie absolut sicher sind, dass die veröffentlichten Daten vollständig frei von xss, Viren usw. sind, ist dies vollständig der Fall sicher in einem Browser anzuzeigen; Sie können es nicht einfach so oder so in Ihre Datenbank schieben. So entstehen SQL-Injektionen.

Unter dem Strich können Sie bis zur Verwendung der Daten nicht wissen, wie "schlechte" Daten aussehen, und alle Wenn Sie die Daten verwenden, müssen Sie sie bereinigen.

Der Versuch, die Daten im Voraus zu reparieren, ist wie das Stopfen von Socken, bevor ein Loch in ihnen ist.

Das Erstellen einer SQL-Abfrage mit Benutzereingaben wird in SQL ausgegeben. Sie sollten daher alles Notwendige tun, um die Daten im SQL-Kontext zu umgehen. Oder vermeiden Sie es, Daten mithilfe von Bindungsparametern zu maskieren.
Obwohl dies technisch gesehen zutrifft, verwenden Sie die Daten manchmal sofort und müssen sie daher sofort bereinigen. Im Wesentlichen argumentieren Sie, dass "Desinfektion von Eingaben" eine falsche und möglicherweise irreführende Bezeichnung ist. Dem würde ich zustimmen. Aber die Handlung, auf die es sich bezieht, ist unbestreitbar manchmal notwendig.
#4
+4
Neil McGuigan
2015-07-30 09:30:48 UTC
view on stackexchange narkive permalink

Es besteht das Risiko, dass XSS-Inhalte in Ihrer Datenbank enthalten sind. Datenbanken sollen von Anwendungen gemeinsam genutzt werden und sind im Vergleich zu Web-Frontends langlebig.

Beispiel: Der neue Praktikant beginnt mit der Arbeit an einer neuen Web-App für die Datenbank, zeigt seinen Chef und bam , sein Login-Cookie befindet sich in St. Petersburg.

Sie möchten Benutzereingaben nicht ändern, sondern Benutzereingaben validieren und lehne es ab, wenn es mögliches XSS enthält. Dies ist mit einem richtigen HTML-Parser wie JSoup ziemlich einfach und schnell. Es ist in Hibernate Validator integriert.

Ich sage nicht, dass Sie Benutzereingaben bei der Ausgabe nicht entgehen sollten. Bei der Anzahl der XSS-Probleme ist es jedoch offensichtlich leicht, einige zu übersehen.

Sie gehen davon aus, dass die Welt Web ist. Es ist nicht. Es gibt auch legitime Gründe für codeähnliche Daten in einer Datenbank. StackExchange zum Beispiel :) Sie sind jedoch sicher richtig zu validieren, z. Ihre Telefonnummer sollte nicht viel mehr als Zahlen und ein paar andere Satzzeichen enthalten.
#5
+3
ThoriumBR
2015-07-30 23:58:15 UTC
view on stackexchange narkive permalink

Ich würde empfehlen, die Eingabe zu validieren und die Ausgabe zu bereinigen. Auf diese Weise können Sie sicherstellen, dass gültige Daten in der Datenbank gespeichert werden und harmlose Daten auf Benutzerseite verbraucht werden.

Wenn ein Feld ein Datum erwartet, stellen Sie sicher, dass Sie ein Datum erhalten. Sie können Daten, Nummern, E-Mails, Postleitzahlen, Telefonnummern und viele Felder einfach überprüfen. Tun Sie es also.

Führen Sie es auf Javascript, auf der Clientseite und erneut auf der Serverseite aus. Wenn Sie auf der Clientseite validieren, können Sie eine Fehlermeldung viel schneller generieren, als bis zum Server zu warten, validiert und zurückgesendet zu werden. Wiederholen Sie dies auf dem Server, denn wenn jemand die clientseitige Validierung deaktiviert, sind Sie weiterhin versichert.

Bereinigen Sie vor dem Speichern der Daten - Sie möchten nicht von einer SQL-Injektion getroffen werden. Verwenden Sie nach Möglichkeit vorbereitete Anweisungen und maskieren Sie jedes Steuerzeichen, wenn dies nicht möglich ist.

Codieren Sie die Daten auf der Ausgabeseite so, dass sie im Backend-Format harmlos sind. Wenn Sie HTML ausgeben, maskieren Sie alle speziellen HTML-Zeichen. Wenn Sie json oder XML ausgeben, führen Sie die Codierung entsprechend durch.

Wie bereits erwähnt, werden durch Filtern und Codieren der Daten in der Eingabegröße die Daten zerstört und Teile von Daten gelöscht, die in bestimmten Kontexten harmlos wären. oder gefährliche Daten aufbewahren. Die Validierung der Eingabe und die Codierung der Ausgabe wäre der beste Ansatz.



Diese Fragen und Antworten wurden automatisch aus der englischen Sprache übersetzt.Der ursprüngliche Inhalt ist auf stackexchange verfügbar. Wir danken ihm für die cc by-sa 3.0-Lizenz, unter der er vertrieben wird.
Loading...