Sind diese beiden Funktionen zur Desinfektion übertrieben?

7
___ answer2940046 ___

Sie machen %code% (wodurch alle %code% in %code% umgewandelt werden) und rufen dann %code% auf, was zu diesem Zeitpunkt nichts mehr erreichen wird, da keine Tags sind.

    
___ answer2940040 ___

Es stimmt, aber dieses Maß an Flucht ist möglicherweise nicht in allen Fällen angemessen. Was, wenn Sie HTML in einer Datenbank speichern möchten?

Best Practices schreiben vor, dass Sie nicht flüchten sollten, wenn Sie Werte empfangen, wenn Sie sie anzeigen. Auf diese Weise können Sie die Anzeige von HTML-Code aus der Datenbank und von HTML-Code aus der Datenbank berücksichtigen, und diese Art von Code gehört auch wirklich dazu.

Ein weiterer Vorteil der Bereinigung ausgehender HTML besteht darin, dass ein neuer Angriffsvektor entdeckt werden kann. In diesem Fall wird das Bereinigen von eingehendem HTML nichts für Werte tun, die bereits in der Datenbank vorhanden sind, während die ausgehende Bereinigung rückwirkend angewendet wird Spezial

Beachten Sie auch, dass %code% in Ihrer ersten Funktion wahrscheinlich keine Auswirkungen hat, wenn alle %code% und %code% zu %code% und %code% geworden sind.

    
___ answer2940101 ___

Um ehrlich zu sein, ich denke der Autor dieser Funktion hat keine Ahnung was XSS und SQL Injektionen sind oder was genau die verwendete Funktion macht.

Um nur zwei Kuriositäten zu nennen:

  • Verwenden Sie %code% nach %code% entfernt die Schrägstriche, die von %code% hinzugefügt wurden.
  • %code% ersetzt die Chatactors %code% und %code% , die in %code% um Tags zu identifizieren.

Außerdem: Im Allgemeinen sind Funktionen, die gegen XSS schützen, nicht geeignet, um SQL-Injektionen zu schützen und umgekehrt. Weil jede Sprache und jeder Kontext eigene Sonderzeichen hat, um die man sich kümmern muss.

Ich rate Ihnen zu erfahren, warum und wie Code-Injektion möglich ist und wie Sie dagegen vorbeugen können. Lerne die Sprachen, mit denen du arbeitest, insbesondere die Sonderzeichen und wie du ihnen entkommen kannst.

Bearbeiten Hier ist ein (wahrscheinlich seltsames) Beispiel: Stellen Sie sich vor, Sie erlauben Ihren Benutzern, einen Wert einzugeben, der als Pfadsegment in einem URI verwendet werden soll, den Sie in einem JavaScript-Code in einem% co_de verwenden % Attributwert. Der Sprachkontext sieht also so aus:

  • HTML-Attributwert
    • JavaScript-Zeichenfolge
      • URI-Pfadsegment

Und damit es mehr Spaß macht: Sie speichern diesen Eingabewert in einer Datenbank.

Um diesen Eingabewert nun korrekt in Ihrer Datenbank zu speichern, müssen Sie nur eine korrekte Codierung für den Kontext verwenden, in dem Sie diesen Wert in Ihre Datenbanksprache (d. h. SQL) einfügen möchten. der Rest spielt (noch) keine Rolle. Da Sie es in eine SQL-String-Deklaration einfügen möchten, sind die kontextabhängigen Sonderzeichen die Zeichen, mit denen Sie diesen Kontext ändern können. Wie bei Zeichenkettendeklarationen sind diese Zeichen (insbesondere) die Zeichen %code% , %code% und %code% , die maskiert werden müssen. Aber wie bereits gesagt, tun vorbereitete Aussagen alles, was für Sie funktioniert, also verwenden Sie sie.

Jetzt, da Sie den Wert in Ihrer Datenbank haben, möchten wir sie korrekt ausgeben. Hier gehen wir vom innersten zum äußersten Kontext über und wenden die richtige Kodierung in jedem Kontext an:

  • Für den URI-Pfadsegment -Kontext müssen wir (mindestens) alle Zeichen entschlüsseln, die uns diesen Kontext ändern lassen; in diesem Fall %code% (das aktuelle Pfadsegment lassen), %code% und %code% (beide verlassen den URI-Pfadkontext). Wir können dafür %code% verwenden.
  • Für den Kontext JavaScript string müssen wir uns um %code% , %code% und %code% kümmern. Wir können dafür %code% verwenden (falls verfügbar).
  • Für den HTML-Attributwert müssen wir auf %code% , %code% , %code% und %code% achten. Wir können hierfür %code% verwenden.

Jetzt alles zusammen:

%Vor%

Wenn nun %code% ist %code% ist die Ausgabe:

%Vor%

Aber die Verwendung all dieser Funktionen in diesen Kontexten ist kein Overkill. Obwohl die Kontexte ähnliche Sonderzeichen haben können, haben sie unterschiedliche Escape-Sequenzen. URI hat die sogenannte prozentuale Kodierung, JavaScript hat Escape-Sequenzen wie %code% und HTML hat Zeichenreferenzen wie %code% . Wenn Sie nicht nur eine dieser Funktionen verwenden, können Sie den Kontext unterbrechen.

    
___ qstnhdr ___ Sind diese beiden Funktionen zur Desinfektion übertrieben? ___ answer2940142 ___

Wenn Sie vorbereitete Anweisungen und SQL-Platzhalter verwenden und niemals Benutzereingaben direkt in Ihre SQL-Strings interpolieren, können Sie die SQL-Bereinigung vollständig überspringen.

Wenn Sie Platzhalter verwenden, wird die Struktur der SQL-Anweisung ( %code% ) getrennt von den Datenwerten, die (schließlich) an die Platzhalter gebunden sind, an die Datenbank-Engine gesendet. Dies bedeutet, dass, abgesehen von größeren Fehlern in der Datenbank-Engine, absolut keine Möglichkeit für die Datenwerte als SQL-Anweisungen missinterpretiert wird. Dies bietet vollständigen Schutz vor SQL-Injection-Angriffen, ohne dass Sie Ihren Fehler beheben müssen Daten für die Speicherung.

    
___ answer2940570 ___

Nein, das ist nicht übertrieben, das ist eine Schwachstelle.

Dieser Code ist vollständig anfällig für SQL-Injection. Sie machen eine mysql_real_escape_string () und dann machen Sie eine stripslashes (). Ein %code% würde also nach mysql_real_escape_string () %code% werden und nach den stripslashes () wieder zu %code% zurückkehren. mysql_real_escape_string () allein ist am besten, um die sql-Injektion zu stoppen. Parametrisierte Abfragebibliotheken wie PDO und ADODB verwenden sie und parametrisierte Abfragen machen es sehr einfach, die SQL-Injektion vollständig zu stoppen.

Fahren Sie fort, testen Sie Ihren Code:

%Vor%

Was wenn:

%Vor%

Gepatcht:

%Vor%

Dieser Code ist auch anfällig für einige Typen XSS:

%Vor%

Was wenn:

%Vor%

gepatcht:

%Vor%

htmlspeicalchars codiert einfache und doppelte Anführungszeichen, stellen Sie sicher, dass die Variable, die Sie drucken, auch in Anführungszeichen eingeschlossen ist, dies macht es unmöglich, "auszubrechen" und Code auszuführen.

    
___ answer2940041 ___

Nun, wenn Sie das Rad nicht neu erfinden wollen, können Sie HTMLPurifier verwenden. Es erlaubt Ihnen, genau zu entscheiden, was Sie wollen und was Sie nicht wollen und verhindert XSS-Angriffe und solche

    
___ answer2946720 ___

Ich wundere mich über das Konzept der Hygienisierung. Sie sagen Mysql, genau das zu tun, was Sie tun sollen: Führen Sie eine Abfrageanweisung aus, die teilweise vom Benutzer der Website erstellt wurde. Sie konstruieren den Satz bereits dynamisch unter Verwendung der Benutzereingabe - Verketten von Zeichenfolgen mit Daten, die vom Benutzer bereitgestellt werden. Sie bekommen, wonach Sie fragen.

Wie auch immer, hier sind noch ein paar Desinfizierungsmethoden ...

1) Bei numerischen Werten sollten Sie zumindest vor oder während der Erstellung des Abfrage-Strings immer mindestens manuell umwandeln: "SELECT field1 FROM tblTest WHERE (id=". (int) $ val. ")";

2) Für Datumsangaben konvertieren Sie zuerst die Variable in den Unix-Zeitstempel. Verwenden Sie dann die Mysql FROM_UNIXTIME () -Funktion, um es zurück in ein Datum zu konvertieren. "SELECT field1 FROM tblTest WHERE (date_field & gt; = FROM_UNIXTIME (". Strtotime ($ val). ")". Dies wird manchmal benötigt, um MySQL zu interpretieren und zu speichern, die sich von den Script- oder OS-Layern unterscheiden / p>

3) Für kurze und vorhersehbare Zeichenfolgen, die einem bestimmten Standard (Benutzername, E-Mail, Telefonnummer usw.) entsprechen müssen, können Sie a) vorbereitete Anweisungen erstellen; oder b) Regex oder andere Datenvalidierung.

4) Für Strings, die keinem echten Standard folgen und überall vor und nach Entweichen oder ausführbaren Code (Text, Memos, Wiki-Markup, Links usw.) enthalten sein können oder nicht, können Sie das tun a) vorbereitete Aussagen machen; oder b) Speichern und Konvertieren von Binär- / Blob-Form - Konvertieren jedes Zeichens in Binär-, Hex- oder Dezimaldarstellung, bevor der Wert sogar an die Abfragezeichenfolge übergeben und beim Extrahieren zurückkonvertiert wird. Auf diese Weise können Sie sich mehr auf die HTML-Validierung konzentrieren, wenn Sie den gespeicherten Wert wieder ausgeben.

    
___
jpjp 30.05.2010, 19:47
quelle

7 Antworten

5

Es stimmt, aber dieses Maß an Flucht ist möglicherweise nicht in allen Fällen angemessen. Was, wenn Sie HTML in einer Datenbank speichern möchten?

Best Practices schreiben vor, dass Sie nicht flüchten sollten, wenn Sie Werte empfangen, wenn Sie sie anzeigen. Auf diese Weise können Sie die Anzeige von HTML-Code aus der Datenbank und von HTML-Code aus der Datenbank berücksichtigen, und diese Art von Code gehört auch wirklich dazu.

Ein weiterer Vorteil der Bereinigung ausgehender HTML besteht darin, dass ein neuer Angriffsvektor entdeckt werden kann. In diesem Fall wird das Bereinigen von eingehendem HTML nichts für Werte tun, die bereits in der Datenbank vorhanden sind, während die ausgehende Bereinigung rückwirkend angewendet wird Spezial

Beachten Sie auch, dass strip_tags in Ihrer ersten Funktion wahrscheinlich keine Auswirkungen hat, wenn alle < und > zu &lt; und &gt; geworden sind.

    
Matchu 30.05.2010, 19:50
quelle
10

Um ehrlich zu sein, ich denke der Autor dieser Funktion hat keine Ahnung was XSS und SQL Injektionen sind oder was genau die verwendete Funktion macht.

Um nur zwei Kuriositäten zu nennen:

Außerdem: Im Allgemeinen sind Funktionen, die gegen XSS schützen, nicht geeignet, um SQL-Injektionen zu schützen und umgekehrt. Weil jede Sprache und jeder Kontext eigene Sonderzeichen hat, um die man sich kümmern muss.

Ich rate Ihnen zu erfahren, warum und wie Code-Injektion möglich ist und wie Sie dagegen vorbeugen können. Lerne die Sprachen, mit denen du arbeitest, insbesondere die Sonderzeichen und wie du ihnen entkommen kannst.

Bearbeiten Hier ist ein (wahrscheinlich seltsames) Beispiel: Stellen Sie sich vor, Sie erlauben Ihren Benutzern, einen Wert einzugeben, der als Pfadsegment in einem URI verwendet werden soll, den Sie in einem JavaScript-Code in einem% co_de verwenden % Attributwert. Der Sprachkontext sieht also so aus:

  • HTML-Attributwert
    • JavaScript-Zeichenfolge
      • URI-Pfadsegment

Und damit es mehr Spaß macht: Sie speichern diesen Eingabewert in einer Datenbank.

Um diesen Eingabewert nun korrekt in Ihrer Datenbank zu speichern, müssen Sie nur eine korrekte Codierung für den Kontext verwenden, in dem Sie diesen Wert in Ihre Datenbanksprache (d. h. SQL) einfügen möchten. der Rest spielt (noch) keine Rolle. Da Sie es in eine SQL-String-Deklaration einfügen möchten, sind die kontextabhängigen Sonderzeichen die Zeichen, mit denen Sie diesen Kontext ändern können. Wie bei Zeichenkettendeklarationen sind diese Zeichen (insbesondere) die Zeichen onclick , " und ' , die maskiert werden müssen. Aber wie bereits gesagt, tun vorbereitete Aussagen alles, was für Sie funktioniert, also verwenden Sie sie.

Jetzt, da Sie den Wert in Ihrer Datenbank haben, möchten wir sie korrekt ausgeben. Hier gehen wir vom innersten zum äußersten Kontext über und wenden die richtige Kodierung in jedem Kontext an:

  • Für den URI-Pfadsegment -Kontext müssen wir (mindestens) alle Zeichen entschlüsseln, die uns diesen Kontext ändern lassen; in diesem Fall \ (das aktuelle Pfadsegment lassen), / und ? (beide verlassen den URI-Pfadkontext). Wir können dafür # verwenden.
  • Für den Kontext JavaScript string müssen wir uns um rawurlencode , " und ' kümmern. Wir können dafür \ verwenden (falls verfügbar).
  • Für den HTML-Attributwert müssen wir auf json_encode , & , " und ' achten. Wir können hierfür < verwenden.

Jetzt alles zusammen:

%Vor%

Wenn nun htmlspecialchars ist $row['user-input'] ist die Ausgabe:

%Vor%

Aber die Verwendung all dieser Funktionen in diesen Kontexten ist kein Overkill. Obwohl die Kontexte ähnliche Sonderzeichen haben können, haben sie unterschiedliche Escape-Sequenzen. URI hat die sogenannte prozentuale Kodierung, JavaScript hat Escape-Sequenzen wie "bar/baz" und HTML hat Zeichenreferenzen wie \" . Wenn Sie nicht nur eine dieser Funktionen verwenden, können Sie den Kontext unterbrechen.

    
Gumbo 30.05.2010 20:08
quelle
3

Sie machen htmlentities (wodurch alle > in &gt; umgewandelt werden) und rufen dann strip_tags auf, was zu diesem Zeitpunkt nichts mehr erreichen wird, da keine Tags sind.

    
Mitch Dempsey 30.05.2010 19:51
quelle
2

Wenn Sie vorbereitete Anweisungen und SQL-Platzhalter verwenden und niemals Benutzereingaben direkt in Ihre SQL-Strings interpolieren, können Sie die SQL-Bereinigung vollständig überspringen.

Wenn Sie Platzhalter verwenden, wird die Struktur der SQL-Anweisung ( SELECT foo, bar, baz FROM my_table WHERE id = ? ) getrennt von den Datenwerten, die (schließlich) an die Platzhalter gebunden sind, an die Datenbank-Engine gesendet. Dies bedeutet, dass, abgesehen von größeren Fehlern in der Datenbank-Engine, absolut keine Möglichkeit für die Datenwerte als SQL-Anweisungen missinterpretiert wird. Dies bietet vollständigen Schutz vor SQL-Injection-Angriffen, ohne dass Sie Ihren Fehler beheben müssen Daten für die Speicherung.

    
Dave Sherohman 30.05.2010 20:19
quelle
2

Nein, das ist nicht übertrieben, das ist eine Schwachstelle.

Dieser Code ist vollständig anfällig für SQL-Injection. Sie machen eine mysql_real_escape_string () und dann machen Sie eine stripslashes (). Ein " würde also nach mysql_real_escape_string () \" werden und nach den stripslashes () wieder zu " zurückkehren. mysql_real_escape_string () allein ist am besten, um die sql-Injektion zu stoppen. Parametrisierte Abfragebibliotheken wie PDO und ADODB verwenden sie und parametrisierte Abfragen machen es sehr einfach, die SQL-Injektion vollständig zu stoppen.

Fahren Sie fort, testen Sie Ihren Code:

%Vor%

Was wenn:

%Vor%

Gepatcht:

%Vor%

Dieser Code ist auch anfällig für einige Typen XSS:

%Vor%

Was wenn:

%Vor%

gepatcht:

%Vor%

htmlspeicalchars codiert einfache und doppelte Anführungszeichen, stellen Sie sicher, dass die Variable, die Sie drucken, auch in Anführungszeichen eingeschlossen ist, dies macht es unmöglich, "auszubrechen" und Code auszuführen.

    
rook 30.05.2010 22:23
quelle
0

Nun, wenn Sie das Rad nicht neu erfinden wollen, können Sie HTMLPurifier verwenden. Es erlaubt Ihnen, genau zu entscheiden, was Sie wollen und was Sie nicht wollen und verhindert XSS-Angriffe und solche

    
nico 30.05.2010 19:50
quelle
-1

Ich wundere mich über das Konzept der Hygienisierung. Sie sagen Mysql, genau das zu tun, was Sie tun sollen: Führen Sie eine Abfrageanweisung aus, die teilweise vom Benutzer der Website erstellt wurde. Sie konstruieren den Satz bereits dynamisch unter Verwendung der Benutzereingabe - Verketten von Zeichenfolgen mit Daten, die vom Benutzer bereitgestellt werden. Sie bekommen, wonach Sie fragen.

Wie auch immer, hier sind noch ein paar Desinfizierungsmethoden ...

1) Bei numerischen Werten sollten Sie zumindest vor oder während der Erstellung des Abfrage-Strings immer mindestens manuell umwandeln: "SELECT field1 FROM tblTest WHERE (id=". (int) $ val. ")";

2) Für Datumsangaben konvertieren Sie zuerst die Variable in den Unix-Zeitstempel. Verwenden Sie dann die Mysql FROM_UNIXTIME () -Funktion, um es zurück in ein Datum zu konvertieren. "SELECT field1 FROM tblTest WHERE (date_field & gt; = FROM_UNIXTIME (". Strtotime ($ val). ")". Dies wird manchmal benötigt, um MySQL zu interpretieren und zu speichern, die sich von den Script- oder OS-Layern unterscheiden / p>

3) Für kurze und vorhersehbare Zeichenfolgen, die einem bestimmten Standard (Benutzername, E-Mail, Telefonnummer usw.) entsprechen müssen, können Sie a) vorbereitete Anweisungen erstellen; oder b) Regex oder andere Datenvalidierung.

4) Für Strings, die keinem echten Standard folgen und überall vor und nach Entweichen oder ausführbaren Code (Text, Memos, Wiki-Markup, Links usw.) enthalten sein können oder nicht, können Sie das tun a) vorbereitete Aussagen machen; oder b) Speichern und Konvertieren von Binär- / Blob-Form - Konvertieren jedes Zeichens in Binär-, Hex- oder Dezimaldarstellung, bevor der Wert sogar an die Abfragezeichenfolge übergeben und beim Extrahieren zurückkonvertiert wird. Auf diese Weise können Sie sich mehr auf die HTML-Validierung konzentrieren, wenn Sie den gespeicherten Wert wieder ausgeben.

    
bob-the-destroyer 01.06.2010 00:50
quelle

Tags und Links