Sichern Sie Ihre Formulare mit Formularschlüsseln

Sicherheit ist ein heißes Thema. Die Sicherheit Ihrer Websites ist für jede Webanwendung äußerst wichtig. Tatsächlich verbringe ich 70% meiner Zeit damit, meine Bewerbungen zu sichern. Eines der wichtigsten Dinge, die wir sichern müssen, sind Formulare. Heute werden wir eine Methode zur Verhinderung von XSS (Cross-Site-Scripting) und Cross-Site-Request-Fälschung von Formularen prüfen.

Warum?

POST-Daten können von einer Website zur anderen gesendet werden. Warum ist das so schlimm? Ein einfaches Szenario…

Ein an Ihrer Website angemeldeter Benutzer besucht während seiner Sitzung eine andere Website. Diese Website kann POST-Daten an Ihre Website senden, beispielsweise mit AJAX. Da der Benutzer auf Ihrer Website angemeldet ist, kann die andere Website auch Postdaten an gesicherte Formulare senden, auf die nur nach einem Login zugegriffen werden kann.

Wir müssen unsere Seiten auch vor Angriffen mit cURL schützen

Wie können wir das beheben??

Mit Formularschlüsseln! Wir fügen jedem Formular einen speziellen Hash (einen Formularschlüssel) hinzu, um sicherzustellen, dass die Daten nur verarbeitet werden, wenn sie von Ihrer Website gesendet wurden. Nach dem Senden eines Formulars überprüft unser PHP-Skript den übergebenen Formularschlüssel anhand des Formularschlüssels, den wir in einer Sitzung festgelegt haben.

Was wir tun müssen:

  1. Fügen Sie jedem Formular einen Formularschlüssel hinzu.
  2. Speichern Sie den Formularschlüssel in einer Sitzung.
  3. Bestätigen Sie den Formularschlüssel nach dem Senden eines Formulars.

Schritt 1: Ein einfaches Formular

Zunächst benötigen wir ein einfaches Formular zu Demonstrationszwecken. Eines der wichtigsten Formulare, das wir sichern müssen, ist das Anmeldeformular. Das Anmeldeformular ist anfällig für brutale Angriffe. Erstellen Sie eine neue Datei und speichern Sie sie als index.php in Ihrem Webstamm Fügen Sie den folgenden Code in den Hauptteil ein:

     Formulare mit Formularschlüsseln sichern   

Jetzt haben wir eine einfache XHTML-Seite mit einem Anmeldeformular. Wenn Sie Formularschlüssel auf Ihrer Website verwenden möchten, können Sie das obige Skript durch Ihre eigene Anmeldeseite ersetzen. Nun geht es weiter zur wirklichen Aktion.

Schritt 2: Klasse erstellen

Wir werden eine PHP-Klasse für unsere Formularschlüssel erstellen. Weil jede Seite nur enthalten kann ein Mit dem Formularschlüssel könnten wir aus unserer Klasse ein Singleton erstellen, um sicherzustellen, dass unsere Klasse korrekt verwendet wird. Da das Erstellen von Singletons ein fortgeschrittenes OOP-Thema ist, überspringen wir diesen Teil. Erstellen Sie eine neue Datei mit dem Namen formkey.class.php und platzieren Sie es in Ihrem Web-root. Jetzt müssen wir über die Funktionen nachdenken, die wir brauchen. Erstens benötigen wir eine Funktion zum Generieren eines Formularschlüssels, damit wir ihn in unser Formular einfügen können. Fügen Sie in Ihrer PHP-Datei den folgenden Code ein:

 

Oben sehen Sie eine Klasse mit drei Teilen: zwei Variablen und einer Funktion. Wir machen die Funktion privat, da diese Funktion nur von uns verwendet wird AusgabeFunktionen, die wir später erstellen werden. In den beiden Variablen werden die Formularschlüssel gespeichert. Diese sind auch privat, da sie nur von Funktionen innerhalb unserer Klasse verwendet werden dürfen.

Nun müssen wir uns überlegen, wie wir unseren Formularschlüssel generieren können. Da unser Formularschlüssel eindeutig sein muss (andernfalls haben wir keine Sicherheit), verwenden wir eine Kombination aus der IP-Adresse des Benutzers, um den Schlüssel an einen Benutzer zu binden, mt_rand (), um ihn eindeutig zu machen, und die Funktion uniqid () um es noch einzigartiger zu machen. Wir verschlüsseln diese Informationen auch mit md5 (), um einen eindeutigen Hash zu erstellen, den wir dann in unsere Seiten einfügen können. Da wir md5 () verwendet haben, kann ein Benutzer nicht sehen, was wir zur Generierung des Schlüssels verwendet haben. Die ganze Funktion:

 // Funktion zum Generieren der privaten Formularschlüssel-Funktion generateKey () // Liefert die IP-Adresse des Benutzers $ ip = $ _SERVER ['REMOTE_ADDR']; // Wir verwenden mt_rand () anstelle von rand (), da es besser ist, Zufallszahlen zu generieren. // Wir verwenden 'true', um eine längere Zeichenfolge zu erhalten. // Eine genaue Beschreibung der Funktion und weitere Beispiele finden Sie unter http://www.php.net/mt_rand. $ uniqid = uniqid (mt_rand (), true); // Rückgabe des Hashes return md5 ($ ip. $ Uniqid); 

Fügen Sie den obigen Code in Ihre ein formkey.class.php Datei. Ersetzen Sie die Funktion durch die neue Funktion.

Schritt 3: Ein Formularschlüssel in unser Formular einfügen

Für diesen Schritt erstellen wir eine neue Funktion, die ein ausgeblendetes HTML-Feld mit unserem Formularschlüssel ausgibt. Die Funktion besteht aus drei Schritten:

  1. Generieren Sie einen Formularschlüssel mit unserer Funktion generateKey ().
  2. Speichern Sie den Formularschlüssel in unserer Variablen $ formKey und in einer Sitzung.
  3. Das HTML-Feld ausgeben.

Wir nennen unsere Funktion outputKey () und machen es öffentlich, weil wir es außerhalb unserer Klasse verwenden müssen. Unsere Funktion wird die private Funktion aufrufen generateKey () So erstellen Sie einen neuen Formularschlüssel und speichern ihn lokal in einer Sitzung. Zuletzt erstellen wir den XHTML-Code. Fügen Sie nun den folgenden Code in unsere PHP-Klasse ein:

 // Funktion zur Ausgabe des Formularschlüssels public function outputKey () // Generiere den Schlüssel und speichere ihn in der Klasse $ this-> formKey = $ this-> generateKey (); // Speichern Sie den Formularschlüssel in der Sitzung $ _SESSION ['form_key'] = $ this-> formKey; // das Echo des Formularschlüssels ausgeben "formKey. "" /> ";

Jetzt fügen wir den Anmeldeformular den Formularschlüssel hinzu, um ihn zu sichern. Wir müssen die Klasse in unsere aufnehmen index.php Datei. Wir müssen die Sitzung auch starten, da unsere Klasse Sitzungen verwendet, um den generierten Schlüssel zu speichern. Dazu fügen wir den folgenden Code oberhalb des Doctype- und Head-Tags ein:

 

Der obige Code ist ziemlich selbsterklärend. Wir starten die Sitzung (weil wir den Formularschlüssel speichern) und laden die PHP-Klassendatei. Danach beginnen wir die Klasse mit neuer formKey (), Dadurch wird unsere Klasse erstellt und in gespeichert $ formKey. Jetzt müssen wir nur noch unser Formular so bearbeiten, dass es den Formularschlüssel enthält:

 
outputKey (); ?>
input type = "password" name = "password" />

Und das ist alles! Weil wir die Funktion erstellt haben outputKey (), Wir müssen es nur in unser Formular aufnehmen. Wir können Formularschlüssel in jedem Formular verwenden, indem Sie einfach hinzufügen outputKey (); ?> Überprüfen Sie nun einfach die Quelle Ihrer Webseite und Sie können sehen, dass dem Formular ein Formularschlüssel beigefügt ist. Der einzige verbleibende Schritt ist das Überprüfen von Anforderungen.

Schritt 4: Validierung

Wir werden das gesamte Formular nicht bestätigen. Nur der Formularschlüssel. Die Validierung des Formulars ist grundlegend für PHP. Tutorials finden Sie im gesamten Web. Lassen Sie uns den Formularschlüssel überprüfen. Da unsere Funktion "generateKey" den Sitzungswert überschreibt, fügen wir unserer PHP-Klasse einen Konstruktor hinzu. Ein Konstruktor wird aufgerufen, wenn unsere Klasse erstellt (oder erstellt) wird. Der Konstruktor speichert den vorherigen Schlüssel in der Klasse Vor wir schaffen ein neues; Wir haben also immer den vorherigen Formularschlüssel, um unser Formular zu bestätigen. Wenn wir dies nicht tun würden, könnten wir den Formularschlüssel nicht überprüfen. Fügen Sie Ihrer Klasse die folgende PHP-Funktion hinzu:

 // Der Konstruktor speichert den Formularschlüssel (falls vorhanden) in unserer Klassenvariablen. function __construct () // Wir benötigen den vorherigen Schlüssel, um ihn zu speichern, wenn (isset ($ _ SESSION ['form_key'])) $ this-> old_formKey = $ _SESSION ['form_key']; 

Ein Konstruktor sollte immer einen Namen haben __konstruieren(). Wenn der Konstruktor aufgerufen wird, überprüfen wir, ob eine Sitzung festgelegt ist. Wenn ja, speichern wir sie lokal in unserer old_formKey Variable.

Jetzt können wir unseren Formularschlüssel validieren. Wir erstellen eine grundlegende Funktion innerhalb unserer Klasse, die den Formularschlüssel validiert. Diese Funktion sollte auch öffentlich sein, da wir sie außerhalb unserer Klasse verwenden werden. Die Funktion überprüft den POST-Wert des Formularschlüssels anhand des gespeicherten Werts des Formularschlüssels. Fügen Sie diese Funktion zur PHP-Klasse hinzu:

 // Funktion, die den Formularschlüssel validiert hat. POST-Daten public function validate () // Wir verwenden den alten formKey und nicht die neu generierte Version if ($ _ POST ['form_key'] == $ this-> old_formKey) // The Schlüssel ist gültig, Rückgabe wahr. wahr zurückgeben;  else // Der Schlüssel ist ungültig, geben Sie false zurück. falsch zurückgeben; 

Innerhalb index.php, Wir überprüfen den Formularschlüssel mithilfe der Funktion, die wir gerade in unserer Klasse erstellt haben. Natürlich validieren wir nur nach einer POST-Anfrage. Fügen Sie den folgenden Code nach $ formKey = new formKey () hinzu;

 $ error = 'Kein Fehler'; // Ist eine Anfrage? if ($ _ SERVER ['REQUEST_METHOD'] == 'post') // Bestätigen Sie den Formularschlüssel if (! isset ($ _ POST ['form_key']) ||! $ formKey-> validate ()) // Form Schlüssel ist ungültig, zeige einen Fehler $ error = 'Formularschlüssel Fehler!';  else // Machen Sie den Rest Ihrer Validierung hier. $ error = 'Kein Formularschlüsselfehler!'; 

Wir haben eine Variable erstellt $ Fehler die speichert unsere Fehlermeldung. Wenn eine POST-Anfrage gesendet wurde, bestätigen wir unseren Formularschlüssel mit $ formKey-> validate (). Wenn dies false zurückgibt, ist der Formularschlüssel ungültig und es wird ein Fehler angezeigt. Beachten Sie, dass wir nur den Formularschlüssel validieren. Sie müssen den Rest des Formulars selbst überprüfen.

In Ihrem HTML-Code können Sie den folgenden Code einfügen, um die Fehlermeldung anzuzeigen:

 

Dies wird das Echo wiedergeben $ Fehler Variable, wenn es gesetzt ist.

Wenn Sie Ihren Server starten und zu gehen index.php, Sie sehen unser Formular und die Meldung "Kein Fehler". Wenn Sie ein Formular absenden, wird die Meldung "Kein Formularschlüsselfehler" angezeigt, da es sich um eine gültige POST-Anforderung handelt. Versuchen Sie nun, die Seite neu zu laden, und akzeptieren Sie, wenn Ihr Browser fordert, dass die POST-Daten erneut gesendet werden. Sie werden sehen, dass unser Skript eine Fehlermeldung auslöst: 'Formularschlüsselfehler!' Ihr Formular ist jetzt vor Eingaben von anderen Websites und Fehlern geschützt, wenn Seiten neu geladen werden! Der Fehler wird auch nach einer Aktualisierung angezeigt, da nach dem Senden des Formulars ein neuer Formularschlüssel generiert wurde. Das ist gut, weil der Benutzer ein Formular jetzt nicht versehentlich zweimal senden kann.

Vollständiger Code

Hier ist der gesamte PHP- und HTML-Code:

index.php

 validate ()) // Formularschlüssel ist ungültig, zeige einen Fehler $ error = 'Formularschlüsselfehler!';  else // Machen Sie den Rest Ihrer Validierung hier. $ error = 'Kein Formularschlüsselfehler!'; ?>     Formulare mit Formularschlüsseln sichern   
outputKey (); ?>

fomrkey.class.php

 old_formKey = $ _SESSION ['form_key'];  // Funktion zum Generieren der Formularschlüsselservicefunktion generateKey () // Liefert die IP-Adresse des Benutzers $ ip = $ _SERVER ['REMOTE_ADDR']; // Wir verwenden mt_rand () anstelle von rand (), da es besser ist, Zufallszahlen zu generieren. // Wir verwenden 'true', um eine längere Zeichenfolge zu erhalten. // Eine genaue Beschreibung der Funktion und weitere Beispiele finden Sie unter http://www.php.net/mt_rand. $ uniqid = uniqid (mt_rand (), true); // Rückgabe des Hashes return md5 ($ ip. $ Uniqid);  // Funktion zur Ausgabe des Formularschlüssels public function outputKey () // Generiere den Schlüssel und speichere ihn in der Klasse $ this-> formKey = $ this-> generateKey (); // Speichern Sie den Formularschlüssel in der Sitzung $ _SESSION ['form_key'] = $ this-> formKey; // das Echo des Formularschlüssels ausgeben "formKey. "" /> "; // Funktion, die den Formularschlüssel validiert hat. POST data public function validate () // Wir verwenden den alten formKey und nicht die neu generierte Version if ($ _ POST ['form_key'] == $ this-> old_formKey) // Der Schlüssel ist gültig, return true. return true; else // Der Schlüssel ist ungültig. return false. return false;?>

Fazit

Durch Hinzufügen dieses Codes zu jedem wichtigen Formular auf Ihrer Website wird die Sicherheit Ihres Formulars erheblich erhöht. Es stoppt sogar das Aktualisieren von Problemen, wie wir in Schritt 4 gesehen haben. Da der Formularschlüssel nur für eine Anfrage gültig ist, ist eine doppelte Posting nicht möglich.

Dies war mein erstes Tutorial, ich hoffe, es gefällt dir und nutze es, um deine Sicherheit zu verbessern! Bitte lassen Sie mich Ihre Meinung über die Kommentare wissen. Hast du eine bessere Methode? Lass uns wissen.

Lesen Sie weiter

  • WordPress verwendet auch Formularschlüssel (benennt es Nonces): Wordpress Nonces
  • Sieben Angewohnheiten zum Schreiben sicherer PHP-Anwendungen
  • Folgen Sie uns auf Twitter oder abonnieren Sie den NETTUTS-RSS-Feed für mehr tägliche Webentwicklungsberichte und -artikel.