Mit PHP sauber werden

Datensicherheit ist wichtig und wird von Designern, Entwicklern und Kunden gleichermaßen oft unterschätzt. Seit PHP 5.2.0 wurde die Datenbereinigung und -validierung durch die Einführung der Datenfilterung erheblich vereinfacht. Heute werden wir uns diese Filter genauer ansehen, wie sie verwendet werden, und einige benutzerdefinierte Funktionen erstellen.

Tutorial-Details

  • Programm: PHP
  • Ausführung: 5.2.0+
  • Schwierigkeit: Anfänger
  • Geschätzte Fertigstellungszeit: 20 Minuten

Einführung

Ich habe immer gedacht, dass es einfach ist, Code in PHP zu schreiben, und noch einfacher, schlechten Code in PHP zu schreiben. Die Verbreitung von PHP im Web wurde durch die Verwendung in beliebten Open-Source-Softwarepaketen wie WordPress, Drupal und Magento sowie in wichtigen Webanwendungen wie Facebook wirklich unterstützt. Da PHP in so vielen verschiedenen Fällen verwendet wird (dynamische Websites, vertiefte Webanwendungen, Blogging-Plattformen, Content-Management-Systeme und E-Commerce sind nur eine Teilmenge der vielen PHP-Anwendungen), ergeben sich die Möglichkeiten für schmutzig Daten und unsichere Systeme sind zahlreich. Dieses Tutorial erklärt einige Methoden von Mit PHP sauber werden: Datenbereinigung und -validierung indem Sie sich auf verschiedene Arten von Dateneingaben konzentrieren und PHP-Filter und benutzerdefinierte Funktionen verwenden.

Warum desinfizieren und validieren?

In diesem Lernprogramm konzentrieren wir uns wirklich auf Dateneingaben, die Benutzer oder externe Quellen bereitstellen. Dies bedeutet, dass wir die Daten, die wir erhalten, nicht kontrollieren. Alles, was wir tun können, ist zu kontrollieren, was damit gemacht wird, nachdem wir es erhalten haben. Es gibt alle Arten von Bedrohungen im Zusammenhang mit der Datensicherheit durch Eingaben von Benutzern und Daten von Drittanbietern.

Etwas un-Beliebte Bedrohungen für die Datensicherheit:

  • Cross-Site-Scripting (XSS): Eine Form der Code-Injektion, bei der ein Skript von einer völlig anderen Website in eine Website eingefügt wird. Dies ist bei weitem die häufigste Sicherheitsanfälligkeit im Internet. Zwei aktuelle, sehr prominente Beispiele dieser Technik sind die Stalk Daily und Mikeyy Twitter Worms von früher dieses Jahres, die schlecht gesäuberte Eingaben verwendeten, um Javascript über eine "infizierte" Twitter-Weboberfläche zu starten.
  • SQL-InjektionDie zweithäufigste Sicherheitsanfälligkeit im Internet ist eine andere Form der Code-Injektion, bei der ein Skript dazu verwendet wird, an einem der zahlreichen ausbeuterischen Verhaltensweisen teilzunehmen, einschließlich (aber nicht beschränkt auf) dem Zugriff auf unbefugte Daten und / oder dem Zugriff auf diese Daten einer Datenbank oder einfach das Einfügen von Code, der innerhalb einer Website dargestellt oder ausgeführt werden soll, wodurch die Website beschädigt oder verändert wird.
  • Cross-Site Request Forgery (CSRF / XSRF): Ein weniger häufiger Exploit, der mehr auf Datenquellen wie Browser- und Sitzungscookies basiert als auf schlecht bereinigte und validierte Dateneingaben. Mit CSRF (ausgesprochen "Seesurfen") können Befehle auf einer Website ohne Erlaubnis des Benutzers ausgeführt werden. Eine beliebte CSRF-Methode ist die Verwendung eines nicht ordnungsgemäß erstellten URI oder src-Werts für Bilddaten, um ein Skript auszuführen, anstatt ein Bild anzuzeigen.
  • Unsachgemäße Daten: Nicht wirklich eine "Sicherheitslücke" an sich, Unsachgemäße Daten können für einen Websitebesitzer oder Datenbankadministrator zu Problemen führen. Häufig können unsachgemäße Daten schlecht codierte Websites beschädigen oder automatisierte Systeme zum Absturz bringen. Ein Beispiel dafür war die Möglichkeit, ganze MySpace-Profilseiten durch das Posten mit allen Arten von HTML / CSS-Hacker zu ändern..
Bildquelle: XKCD

Für unsere Zwecke konzentrieren wir uns nur auf serverseitige Methoden zur Verbesserung der Datensicherheit mit PHP. Schauen wir uns also an, wie die Begriffe "Bereinigung" und "Validierung" in Bezug auf PHP definiert werden. Laut dem PHP-Handbuch:

Validierung wird verwendet, um zu überprüfen oder zu überprüfen, ob die Daten bestimmten Qualifikationen entsprechen. Wenn Sie beispielsweise FILTER_VALIDATE_EMAIL übergeben, wird bestimmt, ob es sich bei den Daten um eine gültige E-Mail-Adresse handelt, die Daten selbst werden jedoch nicht geändert.

Durch die Bereinigung werden die Daten desinfiziert, sodass sie möglicherweise durch das Entfernen unerwünschter Zeichen geändert werden. Wenn Sie beispielsweise FILTER_SANITIZE_EMAIL übergeben, werden Zeichen entfernt, die für eine E-Mail-Adresse ungeeignet sind. Das heißt, die Daten werden nicht überprüft.

Wenn Ihre Website der Nachtclub ist, in den alle einsteigen möchten, überprüft die Validierung die Gästeliste und die IDs an der Tür, während die Bereinigung als der Türsteher fungiert, der unerwünschte Personen aussortiert, die in der Vergangenheit quietschen. Sehen wir uns dazu die PHP Filters Extension an.

Welche Filter habe ich??

Alle PHP-Installationen sind nicht gleich angelegt. Während PHP 5.2.0 die Einführung von Filtern war, verfügen nicht alle Installationen über die gleichen Filter in der Filter-Erweiterung. Die meisten Installationen verfügen über alle Filter, die wir durchgehen werden, aber um Ihnen die Filter-Erweiterung näher zu bringen, werden wir herausfinden, was Sie auf Ihrem Server haben. Im Quellendownload habe ich eine Datei mit dem Namen enthalten getfilters.php Nach der Installation und Ausführung auf Ihrem Server werden alle Ihre Filter (beide Datenfilter, die über den Server verfügbar sind) angezeigt filter_var Funktions- und Stream-Filter verfügbar durch stream_filter_append).

 Echo "

Datenfilter

\ n\ n\ n "; Echo"\ n "; Echo"\ n"; foreach (filter_list () als $ id => $ filter) echo"\ n "; Echo"
ID filternFiltername
$ filter".filter_id ($ filter)."
\ n ";

Zuerst erhalten wir das Array mit der Liste aller verfügbaren Filter mit filter_list, dann durchlaufen wir das Array und geben den Filternamen heraus, ermitteln die zugewiesene ID des Filters und geben diese ID ebenfalls zurück.

Wie verwende ich einen Filter??

PHP-Filter zur Validierung und Desinfektion werden aktiviert, indem mindestens zwei Werte an die PHP-Filter-Erweiterungsfunktion übergeben werden filter_var. Als Beispiel verwenden wir den Sanitize-Filter für eine Ganzzahl wie folgt:

 $ value = '123abc456def'; echo filter_var ($ value, FILTER_SANITIZE_NUMBER_INT);

Im Beispiel haben wir eine Variable $ wert Das wird durch die Filter Extension-Funktion übergeben filter_var Verwendung der FILTER_SANITIZE_NUMBER_INT Filter. Daraus ergibt sich folgende Ausgabe:

 123456

Der Sanitize-Filter für eine Ganzzahl entfernt alle nicht ganzzahligen Zeichen aus der Ausgabe und erzeugt eine saubere Ganzzahl. Innerhalb des Download-Quellcodes können Sie verschiedene Eingaben ausprobieren. Dabei werden verschiedene übliche Filter auf Ihren Eingabewert angewendet. Ich habe eine Reihe verschiedener Beispiel-Strings beigefügt, die Sie ebenfalls testen können.

Was machen die verschiedenen Filter??

Die nachstehende Liste ist nicht vollständig, enthält jedoch die Mehrzahl der Filter, die standardmäßig mit 5.2.0+ -Installationen geliefert werden. Benutzerdefinierte Filter und aus benutzerdefinierten Erweiterungen hinzugefügte Filter sind hier nicht enthalten.

FILTER_VALIDATE_BOOLEAN: Überprüft, ob die an den Filter übergebenen Daten einen booleschen Wert von haben WAHR oder FALSCH. Wenn der Wert ein nicht boolescher Wert ist, wird er zurückgegeben FALSCH. Das folgende Skript würde "TRUE" für die Beispieldaten anzeigen $ value01 würde aber für die Beispieldaten "FALSE" zurückgeben $ value02:

 $ value01 = TRUE; if (filter_var ($ value01, FILTER_VALIDATE_BOOLEAN)) echo 'TRUE';  else echo 'FALSE';  Echo '

'$ value02 = TRUE; if (filter_var ($ value02, FILTER_VALIDATE_BOOLEAN)) echo 'TRUE'; else echo 'FALSE';

FILTER_VALIDATE_EMAIL: Überprüft, ob die an den Filter übermittelten Daten eine möglicherweise gültige E-Mail-Adresse sind. Es wird nicht geprüft, ob die E-Mail-Adresse tatsächlich existiert, sondern nur, dass das Format der E-Mail-Adresse gültig ist. Das folgende Skript würde "TRUE" für die Beispieldaten anzeigen $ value01 würde aber für die Beispieldaten "FALSE" zurückgeben $ value02 (weil dem zweiten der @ domain.tld-Teil der E-Mail-Adresse fehlt):

 $ value01 = '[email protected]'; if (filter_var ($ value01, FILTER_VALIDATE_EMAIL)) echo 'TRUE';  else echo 'FALSE';  Echo '

'$ value02 =' nettuts '; if (filter_var ($ value02, FILTER_VALIDATE_EMAIL)) echo 'TRUE'; else echo 'FALSE';

FILTER_VALIDATE_FLOAT: Überprüft, ob die an den Filter übergebenen Daten ein gültiger Gleitkommawert sind. Das folgende Skript würde "TRUE" für die Beispieldaten anzeigen $ value01 würde aber für die Beispieldaten "FALSE" zurückgeben $ value02 (weil Komma-Trennzeichen in Float-Werten nicht zulässig sind):

 $ value01 = '1.234'; if (filter_var ($ value01, FILTER_VALIDATE_FLOAT)) echo 'TRUE';  else echo 'FALSE';  Echo '

'$ value02 =' 1,234 '; if (filter_var ($ value02, FILTER_VALIDATE_FLOAT)) echo 'TRUE'; else echo 'FALSE';

FILTER_VALIDATE_INT: Überprüft, ob die an den Filter übergebenen Daten ein gültiger ganzzahliger Wert sind. Das folgende Skript würde "TRUE" für die Beispieldaten anzeigen $ value01 würde aber für die Beispieldaten "FALSE" zurückgeben $ value02 (weil Brüche / Dezimalzahlen keine ganzen Zahlen sind):

 $ value01 = '123456'; if (filter_var ($ value01, FILTER_VALIDATE_INT)) echo 'TRUE';  else echo 'FALSE';  Echo '

'$ value02 =' 123.456 '; if (filter_var ($ value02, FILTER_VALIDATE_INT)) echo 'TRUE'; else echo 'FALSE';

FILTER_VALIDATE_IP: Überprüft, ob die an den Filter übermittelten Daten eine möglicherweise gültige IP-Adresse sind. Es wird nicht geprüft, ob sich die IP-Adresse auflösen würde, sondern nur, dass sie in die erforderliche Datenstruktur für IP-Adressen passt. Das folgende Skript würde "TRUE" für die Beispieldaten anzeigen $ value01 würde aber für die Beispieldaten "FALSE" zurückgeben $ value02:

 $ value01 = '192.168.0.1'; if (filter_var ($ value01, FILTER_VALIDATE_IP)) Echo 'TRUE';  else echo 'FALSE';  Echo '

'$ value02 =' 1.2.3.4.5.6.7.8.9 '; if (filter_var ($ value02, FILTER_VALIDATE_IP)) Echo 'TRUE'; else echo 'FALSE';

FILTER_VALIDATE_URL: Überprüft, ob die an den Filter übermittelten Daten eine möglicherweise gültige URL sind. Es wird nicht geprüft, ob die URL aufgelöst werden würde, sondern nur, dass die erforderliche Datenstruktur für URLs passt. Das folgende Skript würde "TRUE" für die Beispieldaten anzeigen $ value01 würde aber für die Beispieldaten "FALSE" zurückgeben $ value02:

 $ value01 = 'http://net.tutsplus.com'; if (filter_var ($ value01, FILTER_VALIDATE_URL)) echo 'TRUE';  else echo 'FALSE';  Echo '

'$ value02 =' nettuts '; if (filter_var ($ value02, FILTER_VALIDATE_URL)) Echo 'TRUE'; else echo 'FALSE';

FILTER_SANITIZE_STRING: Standardmäßig entfernt dieser Filter alle Daten aus einer Zeichenfolge, die in dieser Zeichenfolge ungültig oder nicht zulässig ist. So werden beispielsweise alle HTML-Tags entfernt, z '; echo filter_var ($ value, FILTER_SANITIZE_STRING);

Dieses Skript würde die Tags entfernen und Folgendes zurückgeben:

 Alarm ("STÖRUNG HIER");

FILTER_SANITIZE_ENCODED: Viele Programmierer verwenden PHP urlencode () Funktion, um ihre URL-Codierung zu behandeln. Dieser Filter macht im Wesentlichen dasselbe. So werden beispielsweise Leerzeichen und / oder Sonderzeichen aus einer Eingabezeichenfolge codiert:

 $ value = ''; echo filter_var ($ value, FILTER_SANITIZE_ENCODED);

Dieses Skript codiert die Interpunktion, Leerzeichen und Klammern und gibt dann Folgendes zurück:

 % 3Cscript% 3Ealert% 28% 27TROUBLE% 20HERE% 27% 29% 3B% 3C% 2Fscript% 3E

FILTER_SANITIZE_SPECIAL_CHARS: Mit diesem Filter werden standardmäßig Sonderzeichen wie Anführungszeichen, Et-Zeichen und Klammern (zusätzlich zu Zeichen mit einem ASCII-Wert unter 32) mit HTML-Kodierung versehen. Die Demo-Seite macht es zwar nicht ohne Anzeige des Quellcodes klar (da die HTML-codierten Sonderzeichen interpretiert und ausgegeben werden), aber wenn Sie sich den Quellcode ansehen, wird die Codierung bei der Arbeit angezeigt:

 $ value = ''; echo filter_var ($ value, FILTER_SANITIZE_SPECIAL_CHARS);

Es konvertiert die Sonderzeichen in ihre HTML-kodierten Selbste:

 

FILTER_SANITIZE_EMAIL: Dieser Filter macht genau das, was man denken würde. Es entfernt alle Zeichen, die in E-Mail-Adressen ungültig sind (wie Klammern, Klammern, Doppelpunkte usw.). Angenommen, Sie haben versehentlich Klammern um einen Buchstaben Ihrer E-Mail-Adresse angefügt (fragen Sie nicht nach dem Verwendungszweck):

 $ value = 't (e) [email protected]'; echo filter_var ($ value, FILTER_SANITIZE_EMAIL);

Es entfernt diese Klammern und Sie erhalten Ihre schöne E-Mail-Adresse zurück:

 [email protected]

Dies ist ein hervorragender Filter, der in E-Mail-Formularen zusammen mit FILTER_VALIDATE_EMAIL verwendet werden kann, um Benutzerfehler zu reduzieren oder XSS-Angriffe zu verhindern (da bei früheren XSS-Angriffen die ursprünglichen Daten direkt in einem nicht bereinigten E-Mail-Feld zurückgegeben wurden zum Browser).

FILTER_SANITIZE_URL: Ähnlich wie der Filter zum Entfernen von E-Mail-Adressen macht dieser Filter genau das, was man denkt. Es entfernt alle Zeichen, die in einer URL ungültig sind (wie bestimmte UTF-8-Zeichen usw.). Angenommen, Sie haben versehentlich ein "®" in die URL Ihrer Website eingefügt (wiederum nicht fragen, wie ein Velociraptor dies tun soll):

 $ value = 'http: //net.tuts®plus.com'; echo filter_var ($ value, FILTER_SANITIZE_URL);

Es entfernt das unerwünschte "®" und Sie erhalten Ihre gutaussehende URL zurück:

 http://net.tutsplus.com

FILTER_SANITIZE_NUMBER_INT: Dieser Filter ähnelt dem FILTER_VALIDATE_INT, aber anstatt nur zu prüfen, ob es sich um eine Ganzzahl handelt oder nicht, entfernt er tatsächlich alle Nicht-Ganzzahlen aus dem Wert! Praktisch für nervige Spambots und Betrüger in einigen Eingabeformen:

 $ value01 = '123abc456def'; echo filter_var ($ value01, FILTER_SANITIZE_NUMBER_INT); Echo '
'; $ value02 = '1.2.3.4.5.6.7.8.9'; echo filter_var ($ value02, FILTER_SANITIZE_NUMBER_INT);

Diese dummen Buchstaben und Dezimalzahlen werden gleich ausgegeben:

 123456 123456789

FILTER_SANITIZE_NUMBER_FLOAT: Dieser Filter ähnelt dem FILTER_VALIDATE_INT, aber anstatt nur zu prüfen, ob es sich um eine Ganzzahl handelt oder nicht, entfernt er tatsächlich alle Nicht-Ganzzahlen aus dem Wert! Praktisch für nervige Spambots und Betrüger in einigen Eingabeformen:

 $ value01 = '123abc456def'; echo filter_var ($ value01, FILTER_SANITIZE_NUMBER_FLOAT); Echo '
'; $ value02 = '1.2.3.4.5.6.7.8.9'; echo filter_var ($ value02, FILTER_SANITIZE_NUMBER_FLOAT);

Wieder werden all diese dummen Buchstaben und Dezimalzahlen gleich ausgegeben:

 123456 123456789

Aber was wäre, wenn Sie eine Dezimalzahl wie im nächsten Beispiel beibehalten möchten:

 $ value = '1.23'; echo filter_var ($ value, FILTER_SANITIZE_NUMBER_FLOAT);

Es würde es immer noch entfernen und zurückkehren:

 123

Einer der Hauptgründe, warum FILTER_SANITIZE_NUMBER_FLOAT und FILTER_SANITIZE_INT getrennte Filter sind, besteht darin, dies über ein spezielles Flag "FILTER_FLAG_ALLOW_FRACTION" zu ermöglichen, das als dritter Wert hinzugefügt wird filter_var:

 $ value = '1.23'; echo filter_var ($ value, FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION);

Es würde die Dezimalzahl beibehalten und zurückgeben:

 1,23

Optionen, Flags und Array-Steuerelemente, OH MY!

Das Flag in diesem letzten Beispiel ist nur eine von vielen weiteren Optionen, Flags und Array-Steuerelementen, mit denen Sie genauer steuern können, welche Datentypen bereinigt werden, Definitionen von Trennzeichen, wie Arrays von den Filtern verarbeitet werden, und vieles mehr. Weitere Informationen zu diesen Flags und anderen filterbezogenen Funktionen finden Sie im Abschnitt Filter Extension des PHP-Handbuchs.

Andere Methoden zum Santisieren von Daten mit PHP

Im Folgenden werden einige wichtige ergänzende Methoden zum Bereinigen von Daten mit PHP beschrieben, um zu verhindern, dass "fehlerhafte Daten" auf Ihren Systemen Verwüstungen anrichten. Dies ist besonders nützlich für Anwendungen, die noch PHP 4 ausführen, da sie alle bei ihrer Veröffentlichung verfügbar waren.

htmlspecialchars: Diese PHP-Funktion konvertiert 5 Sonderzeichen in ihre entsprechenden HTML-Entitäten:

  • "&" (kaufmännisches Und) wird zu "&"
  • '' '(doppelte Anführungszeichen) wird' '', wenn ENT_NOQUOTES nicht gesetzt ist.
  • "(einfaches Anführungszeichen) wird nur '' ', wenn ENT_QUOTES gesetzt ist.
  • '<' (less than) becomes '<'
  • ">" (größer als) wird zu ">"

Es wird wie jede andere PHP-String-Funktion verwendet:

 echo htmlspecialchars ('$ string');

htmlentities: Wie auch bei htmlspecialchars konvertiert diese PHP-Funktion Zeichen in ihre entsprechenden HTML-Entitäten. Der große Unterschied ist das ALLES Zeichen, die konvertiert werden können, werden konvertiert. Dies ist eine nützliche Methode zum Verschleiern von E-Mail-Adressen von einigen Bots, die E-Mail-Adressen sammeln, da keine von ihnen zum Lesen von htmlentities programmiert ist.

Es wird wie jede andere PHP-String-Funktion verwendet:

 echo htmlentities ('$ string');

mysql_real_escape_string: Diese MySQL-Funktion schützt vor SQL-Injection-Angriffen. Es wird als bewährte Methode (oder sogar als obligatorische Methode) angesehen, alle Daten, die an eine MySQL-Abfrage gesendet werden, über diese Funktion zu übergeben. Es entgeht allen Sonderzeichen, die problematisch sein könnten und kleine Bobby Tables dazu zwingen, eine weitere Schülerdatenbank zu zerstören.

 $ query = 'SELECT * FROM-Tabelle WHERE value = ". mysql_real_escape_string (" $ string'). " LIMIT 1,1 '; $ runQuery = mysql_query ($ query);

Benutzerdefinierte Funktionen

Für viele Menschen sind diese eingebauten Filter und Funktionen einfach nicht gut genug. Die Datenvalidierung einiger Daten wie Telefonnummern, Postleitzahlen oder sogar E-Mails erfordert häufig eine strengere Validierung und Maskierung. Zu diesem Zweck erstellen viele Benutzer benutzerdefinierte Funktionen zur Überprüfung, und ihre Daten sind real. Ein Beispiel hierfür kann so einfach sein wie die Verwendung einer MySQL-Abfrage, um die Daten in einer Datenbank bekannter Werte nachzuschlagen:

 Funktion checkZipCode ($ value) $ zipcheck = 'SELECT COUNT (*) FROM' Datenbank '.' ZIP-Codes 'WHERE value = "'. filter_var (mysql_real_escape_string ($ value), FILTER_SANITIZE_NUMBER_INT). '"'; $ count = mysql_query ($ zipcheck); if ($ count == 1) return TRUE;  else return FALSE; 

Andere benutzerdefinierte Funktionen können erstellt werden, die sich nicht auf Datenbanken mit bekannten Werten verlassen. Sie können erstellt werden, indem Sie Anführungszeichen prüfen, Schrägstriche entfernen und für das Einfügen in eine Datenbank escapen:

 Funktion cleanString ($ string) $ detagged = strip_tags ($ string); if (get_magic_quotes_gpc ()) $ stripped = striplashes ($ detagged); $ escaped = mysql_real_escape_string ($ stripped);  else $ escaped = mysql_real_escape_string ($ detagged);  return $ escaped; 

Die Möglichkeiten sind unbegrenzt, vor allem wenn Sie reguläre Ausdrücke integrieren, aber in den meisten Fällen sollte die PHP-Filter-Erweiterung den Trick tun.

  • Folgen Sie uns auf Twitter oder abonnieren Sie den Nettuts + RSS-Feed für mehr tägliche Webentwicklungsberichte und -artikel.