Im heutigen Lernprogramm erfahren Sie, wie Sie Ihre CodeIgniter-Anwendung (vor 2.0) vor Angriffen durch Cross-Site Request Forgery schmerzlos schützen können. Die Bibliothek, die wir heute erstellen, wird alle Schutzmechanismen automatisieren und Ihre Website stärker und sicherer machen.
Cross-Site Request Forgery-Angriffe basieren auf ungeschützten Formularen auf Ihren Sites.
Ein Angreifer kann auf seiner Website ein gefälschtes Formular erstellen, beispielsweise ein Suchformular. Dieses Formular kann Eingaben verbergen, die schädliche Daten enthalten. Jetzt wird das Formular nicht wirklich an die Site des Angreifers gesendet, um die Suche durchzuführen. In Wirklichkeit weist das Formular auf Ihre Seite? ˅! Da Ihre Website darauf vertrauen kann, dass das Formular echt ist, durchläuft es die angeforderten (und möglicherweise böswilligen) Aktionen.
Stellen Sie sich vor, ein Benutzer ist bei Ihrer Site angemeldet und wird aus irgendeinem Grund zur Site des Angreifers umgeleitet (Phishing, XSS, Sie nennen es). Das Formular des Angreifers kann auf das Löschformular Ihres Kontos auf Ihrer Website verweisen. Wenn der Benutzer eine "Suche" auf der Angreifer-Site durchführt, wird sein Konto ohne Wissen des Benutzers gelöscht!
Es gibt zahlreiche Möglichkeiten, diese Art von Angriffen zu verhindern.
POST
anfordern, vergleichen Sie das übergebene Token mit dem im Geschäft, und, wenn sie sich unterscheiden, verweigern Sie die Anforderung. Ihre Site muss jedoch noch vor XSS geschützt werden, da diese Methode sonst unbrauchbar wird.Wir müssen für jede Anfrage drei Dinge tun:
POST
anfordern, bestätigen Sie, dass das übergebene Token. Um dies automatisch durchzuführen, verwenden wir CodeIgniter-Hooks. Hooks ermöglichen es uns, alle Aktionen für verschiedene Teile der Anfrage auszuführen. Wir brauchen drei:
Lass uns anfangen. Wir gehen Schritt für Schritt vor, um alles so gründlich wie möglich zu erklären. Wir erstellen die Methode, die das Token zuerst generiert, sodass wir anschließend alles richtig testen können. Erstellen Sie eine Datei in Ihrem System / Anwendung / Haken
Ordner mit dem Namen "csrf.php
"und fügen Sie den folgenden Code ein:
CI = & get_instance ();
Hoffentlich sollte das, was wir oben hinzugefügt haben, für Sie eher einfach erscheinen. Wir erstellen eine Klasse, genannt CSRF-Schutz
, eine Instanzvariable für die CodeIgniter-Instanz, zwei statische Variablen für den Namen des Parameters, in dem das Token gespeichert wird, und eine, um das Token selbst zu speichern, um den Zugriff auf die gesamte Klasse zu ermöglichen. Innerhalb des Klassenkonstruktors (__konstruieren
) rufen wir einfach die CodeIgniter-Instanz ab und speichern sie in unserer entsprechenden Instanzvariablen.
Hinweis: Der "Name des Parameters" ist der Name des Felds, das das Token enthält. In den Formularen ist dies der Name der versteckten Eingabe.
Fügen Sie nach dem Klassenkonstruktor den folgenden Code ein:
/ ** * Erzeugt ein CSRF-Token und speichert es in einer Sitzung. Es wird nur ein Token pro Sitzung generiert. * Dies muss an einen Post-Controller-Hook gebunden sein und vor dem Hook *, der die inject_tokens-Methode () aufruft. * * @return void * @author Ian Murray * / public function generate_token () // Sitzungsbibliothek laden, falls nicht geladen $ this-> CI-> load-> library ('session'); if ($ this-> CI-> session-> userdata (self :: $ token_name) === FALSE) // Generieren Sie ein Token und speichern Sie es in einer Sitzung, da der alte abgelaufen zu sein scheint. self :: $ token = md5 (uniqid (). microtime (). rand ()); $ this-> CI-> session-> set_userdata (self :: $ token_name, self :: $ token); else // Setzt sie auf lokale Variable, um den einfachen Zugriff zu ermöglichen self :: $ token = $ this-> CI-> session-> userdata (self :: $ token_name);
Schritt für Schritt:
FALSCH
, dann ist der token noch nicht vorhanden. Wir müssen sicherstellen, dass das Token übermittelt wurde und gültig ist, falls es sich um eine Anfrage handelt POST
anfordern. Fahren Sie fort und fügen Sie den folgenden Code in Ihr ein csrf.php
Datei:
/ ** * Überprüft ein übermitteltes Token, wenn eine POST-Anforderung erfolgt. * * @return void * @author Ian Murray * / public function validate_tokens () // Ist dies eine Postanforderung? if ($ _SERVER ['REQUEST_METHOD'] == 'POST') // Ist das Tokenfeld gesetzt und gültig? $ posted_token = $ this-> CI-> input-> post (self :: $ token_name); if ($ posted_token === FALSE || $ posted_token! = $ this-> CI-> session-> userdata (self :: $ token_name)) // Ungültige Anforderung, Fehler 400 senden. show_error ('Anforderung war ungültig. Token stimmten nicht überein. ', 400);
POST
Antrag, was bedeutet, dass tatsächlich ein Formular übermittelt wurde. Wir prüfen das, indem wir uns die ansehen REQUEST_METHOD
innerhalb des $ _SERVER
super global. $ this-> CI-> input-> post (self :: $ token_name)
ist FALSCH
, dann wurde der token nie gebucht. Das ist der lustige Teil! Wir müssen die Jetons in allen Formen injizieren. Um uns das Leben leichter zu machen, werden wir zwei Meta-Tags in unsere einfügen (Schienenähnlich). Auf diese Weise können wir das Token auch in AJAX-Anforderungen aufnehmen.
Hängen Sie den folgenden Code an Ihre csrf.php
Datei:
/ ** * Dadurch werden in alle POST-Formulare mit dem csrf-Token ausgeblendete Tags eingefügt. * Spritzt auch Meta-Header ein der Ausgabe (falls vorhanden) für den einfachen Zugriff * von JS-Frameworks. * * @return void * @author Ian Murray * / public function inject_tokens () $ output = $ this-> CI-> output-> get_output (); // In Form injizieren $ output = preg_replace ('/ (<(form|FORM)[^>] * (method | METHOD) = "(post | POST)" [^>] *>) / ',' $ 0', $ output); // Injizieren in $ output = preg_replace ('/ (<\/head>) / ',''. "\ n". ''. "\ n". '$ 0', $ Ausgabe); $ this-> CI-> output -> _ display ($ output);
display_override
Hook, müssen wir die generierte Ausgabe von CodeIgniter abrufen. Wir machen dies mit der $ this-> CI-> output-> get_output ()
Methode. POST
. Header
(Falls vorhanden). Dies ist einfach, da das schließende Tag nur einmal pro Datei vorhanden sein sollte. display_override
Hook, wird die Standardmethode zum Anzeigen Ihrer Ansicht nicht aufgerufen. Diese Methode beinhaltet alle möglichen Dinge, die wir nicht tun sollten - nur um Code einzufügen. Wenn wir es selbst nennen, wird das gelöst. Zu guter Letzt müssen wir die Hooks selbst erstellen - also werden unsere Methoden aufgerufen. Fügen Sie den folgenden Code in Ihre ein system / application / config / hooks.php
Datei:
// // CSRF-Schutzhaken, berühren Sie diese nicht, wenn Sie nicht wissen, was Sie // tun. // // DER AUFTRAG DIESER HAKS IST EXTREM WICHTIG !! // // DAS MUSS IN DER HOOK LIST von post_controller_constructor an erster Stelle stehen. $ hook ['post_controller_constructor'] [] = array (// Beachten Sie das "[]", dies ist nicht der einzige post_controller_constructor-Hook 'class' => 'CSRF_Protection', 'function' => 'validate_tokens', 'filename' = > 'csrf.php', 'filepath' => 'hooks'); // Generiert das Token (MUSS NACH DER BESTÄTIGUNG VORGESCHLAGEN WERDEN, ABER VOR DEM CONTROLLER // WIRD ES AUSGEFÜHRT, ANDERERWEISE NUTZT DER BENUTZER KEINEN ZUGANG ZU EINEM BESTIMMTEN FORMULAR). $ hook ['post_controller_constructor'] [] = array (// Beachten Sie das "[]", dies ist nicht der einzige post_controller_constructor-Hook 'class' => 'CSRF_Protection'), 'function' => 'generate_token', 'filename' = > 'csrf.php', 'filepath' => 'hooks'); // Dies injiziert Token in alle Formulare. $ Hook ['display_override'] = array ('class' => 'CSRF_Protection', 'function' => 'inject_tokens', 'filename' => 'csrf.php', 'filepath' => 'Haken');
post_controller_constructor
Haken, also müssen wir diese Klammern hinzufügen ("[]
"). Weitere Informationen finden Sie in der Dokumentation zu CodeIgniter-Hooks. post_controller_constructor
, generiert das Token für den Fall, dass es noch nicht generiert wurde. bilden
und das Header
. Mit minimalem Aufwand haben wir uns eine schöne Bibliothek zusammengestellt.
Sie können diese Bibliothek in jedem Projekt verwenden und Ihre Site wird automatisch vor CSRF geschützt.
Wenn Sie zu diesem kleinen Projekt beitragen möchten, hinterlassen Sie bitte einen Kommentar oder verzweigen Sie das Projekt auf GitHub. Alternativ ist ab CodeIgniter v2.0 jetzt auch ein Schutz vor CSRF-Angriffen in das Framework integriert!