it-swarm.com.de

Was ist der beste Weg, um Benutzereingaben in PHP zu bereinigen?

Was ist der beste Weg, um Benutzereingaben zu bereinigen?

Dies sind Dinge, die ich mache, wenn Benutzer Daten senden:

  1. substr wenn über begrenzte Werte gefunden.
  2. htmlspecialchars() + ent_quotes + UTF-8
  3. str_replace '<' '>' Benutzereingabe

Was muss noch getan werden?

31
user2615947

"Desinfektion" ist ein nicht hilfreicher und irreführender Begriff. Hier gibt es zwei verschiedene Tiere:

  1. Ausgabe entweicht. Dies ist ein Problem der Ausgangsstufe. Wenn Sie variable Zeichenfolgen in eine größere Zeichenfolge mit umgebender Syntax einfügen, müssen Sie die injizierte Zeichenfolge verarbeiten, damit sie den Anforderungen dieser Syntax entspricht. Was genau diese Verarbeitung ist, hängt vom Kontext ab: Wenn Sie Text in HTML einfügen, müssen Sie diesen Text zum Zeitpunkt der Erstellung des HTML-Codes HTML-maskieren. Wenn Sie Text in SQL-Abfragen einfügen, müssen Sie den Text zum Zeitpunkt der Erstellung der Abfrage mit SQL-Escapezeichen versehen. (*)

  2. Eingabevalidierung. Dies ist ein Problem in der Eingabestufe, das sicherstellt, dass die Benutzereingabe innerhalb der akzeptierten möglichen Werte für ein Datenelement liegt. Dies ist in erster Linie eine Frage der Geschäftsregeln, die feldweise zu berücksichtigen sind, obwohl es einige Arten der Validierung gibt, die für fast alle Eingabefelder sinnvoll sind (hauptsächlich die Überprüfung auf Steuerzeichen).

Die Eingabevalidierung hat Auswirkungen auf die Sicherheit, da sie den Schaden mindern kann, wenn Sie einen Fehler beim Entweichen Ihrer Ausgabe gemacht haben. Es reicht jedoch nicht aus, sich auf die Eingabevalidierung als Ihre einzige Textverarbeitungsmaßnahme zu verlassen, da Sie dem Benutzer immer erlauben müssen, einige Zeichen zu verwenden, die speziell für die einige Syntax oder die andere sind. Sie möchten eine Webseite über fish & chips Und einen Kunden in Ihrer Datenbank namens O'Reilly Haben können.

"Desinfektion" verwechselt diese beiden Konzepte und ermutigt Sie, sie in derselben Phase anzusprechen, die niemals konsequent funktionieren kann. Ein gängiges Anti-Pattern ist das HTML-Escape aller Ihrer Eingaben. Sie wissen jedoch nicht, ob jedes Eingabeelement in dieser Eingabeverarbeitungsphase in HTML (und nur in HTML ausgegeben) ausgegeben wird. Wenn du das tust:

  • sie haben HTML-codiertes Material in der Datenbank, das nicht zerschnitten und verarbeitet werden kann, ohne dass die Entitätsreferenzen im Weg stehen.

  • wenn Sie Inhalte aus Daten erstellen müssen, die kein HTML-Code sind, z. B. eine E-Mail senden oder eine CSV-Datei schreiben, enthalten Sie hässlichen Text.

  • wenn Sie Inhalte in Ihrer Datenbank von einer anderen Quelle erhalten, sind diese möglicherweise nicht HTML-maskiert. Wenn Sie sie also direkt auf die Seite ausgeben, sind Sie immer noch XSS-Schwachstellen.

Das Konzept „Desinfektion“ sollte durch Feuer zerstört, dann ertrunken, in kleine Stücke geschnitten und wieder durch etwas Feuer zerstört werden.

(*: In beiden Fällen ist es klüger, eine Methode zu wählen, die die Verarbeitung implizit für Sie ausführt, damit Sie nichts falsch machen: Verwenden Sie eine HTML-Vorlagensprache, die standardmäßig der Ausgabe entgeht, und eine Datenzugriffsebene, die parametrisierte Abfragen oder verwendet Objektrelationale Zuordnung. Ähnliches gilt für andere Arten der Escape-Funktion: Ziehen Sie einen standardkonformen XML-Serialisierer dem manuellen XML-Escapeing vor, verwenden Sie einen Standard-JSON-Serialisierer, um Daten an JavaScript zu übergeben, usw.)

substr wenn über begrenzte Werte gefunden.

Meinen Sie damit, zu lange Eingabezeichenfolgen abzuschneiden? Dies ist als eine Form der Eingabevalidierung in Ordnung, bei der Ihre Geschäftsregeln einen gültigen Grund haben, die Länge einer Eingabe zu begrenzen. Möglicherweise möchten Sie jedoch lieber einen Fehler an den Benutzer zurückgeben, wenn Sie eine zu lange Eingabezeichenfolge haben, da es je nach Feld möglicherweise nicht angebracht ist, Daten stillschweigend zu verwerfen.

htmlspecialchars () + ent_quotes + UTF-8

Dies ist eine Ausgabe, die entweicht. Tun Sie dies für die Werte an dem Punkt, an dem Sie sie in HTML ablegen, nicht für die Eingabe. Wenn Sie native PHP Templating) verwenden, möchten Sie möglicherweise eine Verknüpfung definieren, um die Eingabe zu beschleunigen, z. B.:

function h($s) {
    echo htmlspecialchars($s, ENT_QUOTES, 'utf-8')l
}
...

<p>Hello, <?php h($user['name']); ?>!</p>

str_replace <> Benutzereingabe

Wozu? Wenn Sie HTML-Escape korrekt verwenden, sind diese Zeichen vollkommen in Ordnung, und sofern in Ihren Geschäftsregeln nicht anders angegeben, kann die Aufnahme in ein Feld durchaus gültig sein - genau wie beide Zeichen für mich gültig sind, um dieses Kommentarfeld für SO einzugeben.

Natürlich möchten Sie sie möglicherweise bei der Eingabevalidierung für bestimmte Felder nicht zulassen - Sie möchten sie nicht in einer Telefonnummer haben.

49
bobince

Ich benutze die OWASP PHP Filter. Sie sind wirklich einfach zu bedienen und effektiv.

https://www.owasp.org/index.php/OWASP_PHP_Filters

Der Quellcode ist gut lesbar. Es gibt dort viele schmerzhafte Lektionen.

11
mgjk

Da dies ein Problem von vor einigen Jahren ist, ändern sich einige Dinge und externe Links klappen im Allgemeinen, da Websites Links, die möglicherweise auf anderen Websites vorhanden sind, nicht pflegen oder adressieren.

Also weiter, PHP hat sich ein wenig weiterentwickelt und viele Leute fragen nach der Bereinigung von Eingaben, aber bis jetzt ist die Verwendung von filter_var Dünn, obwohl sie nicht perfekt ist Nach meiner Lektüre binär sicher.

Sie erhalten also eine E-Mail-Adresse. Wenn Sie HTML5 nicht verwenden, wenn Sie es in Verbindung mit PHP filter_var Verwenden sollten), ist Ihre Site sicherer als jemand, der schreibt Eine Routine zum Bereinigen einer Eingabe, die keine HTML5-Eingaben verwendet. Das Schreiben von Code zur Abwärtskompatibilität für nicht HTML5-kompatible Browser ist völlig sinnlos und eine Verschwendung Ihrer Ressourcen und Zeit.

Das andere Problem der Sicherheit besteht darin, dass die Werte von $ _GET und $ _POST volatil sind und sich von guten Daten zu schlechten Daten ändern oder extern ändern können. Daher ist jede Bereinigungsroutine, die sie verwendet und bereinigte Eingaben an sie zurückgibt, nur reif dafür Probleme ... $ _REQUEST-Array ist sicherer. Sobald es in Ihrem sicheren Array festgelegt wurde, kann es nicht mehr geändert werden. Füllen Sie also Ihr sicheres Array, indem Sie Eingaben und filter_var in das sichere Array übernehmen.

Wie ich Eingaben bereinige, ist ungefähr so ​​...

$someSafeArray = array(
        "thefield"=>FILTER_SANITIZE_STRING,
        "theNumberfield"=>FILTER_SANITIZE_NUMBER,
        "theEmailfield"=>FILTER_SANITIZE_EMAIL
        );
foreach( $someSafeArray as $fld=>&$val)
    $val = filter_var( trim( $_REQUEST[$fld] ), $val );

Dies gibt also alle Felder (von den Schlüsseln) zurück und die bereinigten Eingaben werden dann in die Werte dieser Schlüssel im sicheren Array eingefügt.

Dies bedeutet, dass ich die Schlüssel einer Whitelist (Array) verwende, um NUR die Eingaben zu übernehmen, die ich als gültige Felder bezeichne. Ich habe zu viele Leute gesehen, die "dynamische" Formularprozessoren angeboten haben, die JEDE Eingabe akzeptieren, NEIN !!! Sie sollten nur Datenströme akzeptieren, für die Ihr Code/Formular ausgelegt ist.

SALZEN Sie Ihre Seite mit einem Wert, mit dem Ihr empfangendes Formular das richtige Hashing neu berechnen kann, um zu überprüfen, ob Ihr Formular vom Server ausgegeben wurde. LEERE Felder. Ich füge mindestens eine leere Firld hinzu, die schreibgeschützt ist und wie Hashing-Felder ausgeblendet ist Wenn das Formular verschoben wird oder nicht, füllt ein Bot alle Felder mit Daten, um zu versuchen, die Seite zu öffnen.

SO Ködern Sie Ihre Seite mit ein paar Dummy-Feldern wie ...

<input name="userlogin" type="hidden" value="" readonly />
<input name="empty" type="hidden" value="" readonly />

wenn das Formular mit einem Wert im Wertfeld einer der Eingaben auf Ihrem Server eingetroffen ist, können Sie auch die Formularverarbeitung beenden, die Benutzer-IP protokollieren und blockieren, da es sich entweder um einen Bot oder einen Hacker handelt.

Injection ist nicht nur ein SQL-Problem, sondern auch ein PHP Seitenproblem). Achten Sie also darauf, welche Felder Sie akzeptieren, was für salt und bait in Ihrem Formular mit und betreiben eine weiße Liste.

Hören Sie auf, GETs zu verwenden, um Steuerparameter zu übergeben. Verwenden Sie ein Sitzungscookie, da dies die Eingaben in das Skript reduziert. Wenn ich eine URL vom Typ GET verwende, ist dies nur eine subversive Taktik und ermöglicht die Überwachung von Benutzern, die Variablen in die URL und andere Dinge eingeben zu versuchen und zu hacken.

Ich habe einen solchen Prozess verwendet, seit ich vor Einführung der Funktion filter_var Seiten gesalzen habe, ohne dass eine Datenbank zur Validierung eingehender Seiten erforderlich war, und es war etwas, das mir wiederholt von sogenannten Fachleuten gesagt wurde, war nicht möglich Das einzige, was ich dazu sagen muss, ist, dass "es ist, wenn Sie in der Lage sind, außerhalb der Kesselplatte zu denken. (Box)" und einfach genug, um Hacking-Versuche zu vereiteln, Ihre Formularseiten zu sichern.

4
Mark Giblin

Ich persönlich würde niemals str_replace auf < und >, nur Strip-Tags , HTML-Sonderzeichen , Codierung von HTML-Entitäten , mysql_real_escape_string usw. bei Benutzereingaben.

Was Sie berücksichtigen müssen, ist, wie die Daten dargestellt werden?

  • Wird es am Frontend ausgegeben?
  • Geht es in die Datenbank?
  • Wird es in Javascript am Frontend verwendet?
  • Wie wäre es mit der Aufnahme von Dateien?

Wenn es in das Front-End geht, müssen Sie es htmlentities und strip_tags imo, so können Sie sicher sein, dass sie nicht versuchen, unerwünschten Code auszuführen.

Außerdem ist das Entfernen von Schrägstrichen eine ziemlich große Überlegung. Ich habe kürzlich ein XSS im WP Platinum SEO-Plugin) gefunden, mit dem Sie Javascript-Code über den Parameter $ _GET ['s'] ausführen können, indem Sie alles in codieren Escape-Hex-Code (\\ x41 = A).

Wenn Sie Daten in die Datenbank eingeben, sehen Sie sich PDO-vorbereitete Abfragen sowie mysql_real_escape_string an. Dies sollte Ihre Datenbankeingaben ziemlich gut sichern.

Wenn Sie Benutzereingaben verwenden, um Dateien anzufordern, stellen Sie sicher, dass diese nicht anfällig für Poison Null Byte Angriffe sind, und entfernen Sie meiner Meinung nach immer alle Schrägstriche in den Datei-Includes, um sicherzustellen, dass sie nicht auf den Speicherort zugreifen können erwünscht. Ich würde auch empfehlen, allow_url_include/allow_url_fopen in Ihrer php.ini-Datei auszuschalten.

Ich hoffe das hilft!

0
DarkMantis