Entwickler.CSRFProtection History

Hide minor edits - Show changes to markup

 
 
April 01, 2011, at 11:41 PM by tthelen -
Added lines 1-2:

(:redirect 'http://docs.studip.de/develop/Entwickler/CSRFProtection':)

 
 
March 10, 2011, at 01:33 PM by mlunzena -
Changed lines 29-31 from:

- ob es ein GET-Request ist, um dann die weitere Überprüfung abzubrechen - ob es ein XHR ist (also Ajax mit jQuery oder prototype), um dann die weitere Überprüfung abzubrechen - ob der mitgeschickte Parameter "security_token" existiert und mit dem Token aus der Session übereinstimmt

to:
  • ob es ein GET-Request ist, um dann die weitere Überprüfung abzubrechen
  • ob es ein XHR ist (also Ajax mit jQuery oder prototype), um dann die weitere Überprüfung abzubrechen
  • ob der mitgeschickte Parameter "security_token" existiert und mit dem Token aus der Session übereinstimmt
 
 
March 10, 2011, at 01:32 PM by mlunzena -
Changed line 27 from:

Um Stud.IP vor gefälschten Request zu schützen, muss nun jeder POST-Request (aber nicht Ajax) einen zusätzlichen Parameter "security_token" mitschicken, dessen Wert mit einem in der Session befindlichen verglichen wird. Um genau zu sein, wird für jeden Nutzer zu Beginn seiner Session ein 256-Bit-Token erzeugt und in der $_SESSION abgelegt. Jedes(!) Stud.IP-POST-Formular wurde um ein input[@type=hidden]-Element bereichert, dass diesen Token mitschickt. Sobald ein Request bei Stud.IP eintrifft, wird überprüft:

to:

Um Stud.IP vor gefälschten Request zu schützen, muss nun jeder POST-Request (aber nicht Ajax) einen zusätzlichen Parameter "security_token" mitschicken, dessen Wert mit einem in der Session befindlichen verglichen wird. Um genau zu sein, wird für jeden Nutzer zu Beginn seiner Session ein 256-Bit-Token erzeugt und in der $_SESSION abgelegt. Jedes(!) Stud.IP-POST-Formular wurde um ein input[@type=hidden]-Element bereichert, dass diesen Token mitschickt. Sobald ein Request bei Stud.IP eintrifft, wird überprüft:

 
 
March 10, 2011, at 01:31 PM by mlunzena -
Changed lines 26-27 from:

<TODO: (mlunzena) Wie funktioniert es?>

to:

Um Stud.IP vor gefälschten Request zu schützen, muss nun jeder POST-Request (aber nicht Ajax) einen zusätzlichen Parameter "security_token" mitschicken, dessen Wert mit einem in der Session befindlichen verglichen wird. Um genau zu sein, wird für jeden Nutzer zu Beginn seiner Session ein 256-Bit-Token erzeugt und in der $_SESSION abgelegt. Jedes(!) Stud.IP-POST-Formular wurde um ein input[@type=hidden]-Element bereichert, dass diesen Token mitschickt. Sobald ein Request bei Stud.IP eintrifft, wird überprüft:

- ob es ein GET-Request ist, um dann die weitere Überprüfung abzubrechen - ob es ein XHR ist (also Ajax mit jQuery oder prototype), um dann die weitere Überprüfung abzubrechen - ob der mitgeschickte Parameter "security_token" existiert und mit dem Token aus der Session übereinstimmt

Diese Überprüfung findet automatisch am Ende von #page_open statt, in der Annahme, dass dann die notwendige Session existiert.

Fällt die Überprüfung negativ auf, wird ein Fehler (Status 403) gemeldet und die weitere Bearbeitung abgebrochen.

Changed lines 39-57 from:

<TODO: (mlunzena) Was muss ich tun?>

Ich habe am Dienstag diesen StEP eingebaut und aus Zeitmangel noch nicht offiziell vorgestellt. Die API-Dokumentation befindet sich schon in der [Hilfe.]http://hilfe.studip.de/api/class_c_s_r_f_protection.html

++Was wurde getan?++

Um Stud.IP vor gefälschten Request zu schützen, muss nun jeder POST-Request (aber nicht Ajax) einen zusätzlichen Parameter "security_token" mitschicken, dessen Wert mit einem in der Session befindlichen verglichen wird. Um genau zu sein, wird für jeden Nutzer zu Beginn seiner Session ein 256-Bit-Token erzeugt und in der $_SESSION abgelegt. Jedes (!) Stud.IP-POST-Formular wurde um ein input[@type=hidden]-Element bereichert, dass diesen Token mitschickt. Sobald ein Request bei Stud.IP eintrifft, wird überprüft:

- ob es ein GET-Request ist, um dann die weitere Überprüfung abzubrechen - ob es ein XHR ist (also Ajax mit jQuery oder prototype), um dann die weitere Überprüfung abzubrechen - ob der mitgeschickte Parameter "security_token" existiert und mit dem Token aus der Session übereinstimmt

Diese Überprüfung findet automatisch am Ende von #page_open statt, in der Annahme, dass dann die notwendige Session existiert.

Fällt die Überprüfung negativ auf, wird ein Fehler (Status 403) gemeldet und die weitere Bearbeitung abgebrochen.

++ Was muss ich als Entwickler in Zukunft beachten? ++

to:

Zunächst ein Link zur API-Dokumentation http://hilfe.studip.de/api/class_c_s_r_f_protection.html

Changed line 44 from:

[code]

to:

[@

Changed lines 49-52 from:

[/code]

  • Ganz wichtig:** Diese Methode darf ++NICHT++ aufgerufen werden, wenn es sich um ein GET-Formular handelt, da dann der Token in die URL wandert und damit über den Referer-Header an Dritt-Seiten übertragen wird. In diesem Fall wird der Schutz unwirksam. :no: :no: :no:
to:

@]

Ganz wichtig: Diese Methode darf NICHT aufgerufen werden, wenn es sich um ein GET-Formular handelt, da dann der Token in die URL wandert und damit über den Referer-Header an Dritt-Seiten übertragen wird. In diesem Fall wird der Schutz unwirksam.

Changed lines 55-61 from:

Schwierigkeiten ergeben sich folgende:

1.) Der versteckte Parameter darf niemals in eine URL gelangen, da dies alle Bemühungen über den Haufen werfen würde. Gerät der Token in die Hände eines Angreifers, kann dieser wieder beliebige Anfragen stellen. Dieses Problem gibt es aber natürlich mit der derzeitigen Lösung ebenso und kann mit geringem (Qualitätskontroll-)Aufwand verhindert werden.

2.) Es müssen alle Formulare gefunden werden, um ihnen den versteckten Parameter mitzugeben. Das ist mit ein den üblichen Tools (sed, grep…) relativ unproblematisch möglich.

3.) Die vorhandenen Tickets, die über GET-Requests versendet werden, müssen ummodelliert werden. Der Schwierigkeitsgrad ist noch nicht abzuschätzen, sollte aber erfahrungsgemäß im Rahmen liegen.

to:
  1. Der versteckte Parameter darf niemals in eine URL gelangen, da dies alle Bemühungen über den Haufen werfen würde.
    Gerät der Token in die Hände eines Angreifers, kann dieser wieder beliebige Anfragen stellen.
  2. Die vorhandenen Tickets, die über GET-Requests versendet werden, müssen ummodelliert werden. Bisher ist dort die Umstellung noch nicht erfolgt
  3. Wenn ein seiteneffektbehafteter Request laut Stud.IP-Code eigentlich per POST verschickt werden soll, ein Angreifer aber kurzerhand einen GET-Link platziert, benötigt der Request keinen Sicherheits-Token, da automatisch lediglich bei POST-Requests überprüft wird. Daraus ergeben sich folgende Konsequenzen:
    1. Formulare müssen trotzdem wie oben beschrieben behandelt werden.
    2. Die Auswertung muss in Version 2.2 für jede Routine, die Seiteneffekte auslöst, händisch ausgewertet werden. D.h. dass also alle Stellen im Code identifiziert und um die Auswertung ergänzt werden müssen.
    3. Vorbereitend wurde die Klasse CSRFProtection um die Methode #verifyUnsafeRequest ergänzt. Wenn man eine Stelle im Code gefunden hat, die eigentlich per POST (genauer: alle außer GET oder HEAD) einen Seiteneffekt bewirkt, muss dort folgender Code eingefügt werden:
      CSRFProtection::verifyUnsafeRequest();
    
    
    Der Aufruf überprüft, dass:
    1. es sich um einen unsicheren Request handelt (gemäß RFC 2616)
    2. dieser Request das Sicherheits-Token trägt
    3. das Token mit dem in der Session befindlichen übereinstimmt
    Ist das nicht der Fall gibt es eine MethodNotAllowed-Exception, falls der Request nicht unsicher ist, oder eine InvalidSecurityTokenException, falls das Token nicht übereinstimmt.
 
 
March 10, 2011, at 12:30 PM by mlunzena -
Added lines 2-3:

(:toc:)

 
 
March 10, 2011, at 12:30 PM by mlunzena -
Added lines 1-23:

CSRFProtection - Schutz vor Cross-Site-Request-Forgeries

Problem

CSRF (oder auch XSRF) steht für "Cross-Site Request Forgery"—also in etwa seitenübergreifende Aufrufmanipulation. Diese Angriffsmethode funktioniert so, dass dem Nutzer schadhafter Code oder ein Link untergeschoben wird, der dann mit den Rechten des Nutzers eigentlich unauthorisierte Befehle ausführt (wie zum Beispiel das Absenden von kompromittierenden Nachrichten).

Einfache Beispiele lassen sich zum Beispiel bei Wikipedia finden.

Vor zwei Jahren hatte data-quest einen entsprechenden Anlauf getätigt, der letztlich u.a. im Einbau des Bilder-Proxys endete. Gefährliche Aktionen können seitdem mit Stud.IP-Tickets abgesichert werden. Derzeit wird #check_ticket in 14 Dateien verwendet (wie zB den Studiengruppen, der Administration von Plugins und ihren Rollen, dem Gästebuch).

Augenscheinlich gibt es damit aber noch einige Stellen, die ebenfalls abgesichert werden müssten. Die derzeit verwendete Lösung müsste konsequenterweise an jeder entsprechenden Stelle auch tatsächlich eingesetzt werden. Außerdem bestehen Probleme bei der Verwendung mehrerer Tabs, da die gegenwärtige Lösung lediglich ein valides Ticket kennt.

Dieser vorgeschlagene StEP möchte CSRF/XSRF verhindern, indem jeder "gefährliche" Webrequest geprüft wird. Tim Berners-Lee Axiomen folgend, werden alle Anfragen in seiteneffektfreie und -auslösende Unterschieden. Der Aufruf des Gästebuchs sollte seiteneffektfrei sein. Das Absenden eines Eintrags an das Gästebuch löst Seiteneffekte (naiv: Datenbankänderungen) aus.

Vereinfacht sollen laut Berners-Lee seiteneffektfreie Request über GET und die übrigen mit POST gesendet werden.

Dieser StEP ergänzt jeden POST-Request um einen weiteren Wert, indem jedes Formular einen versteckten Parameter mitliefert. Der Server prüft beim Eintreffen eines POST-Request, ob der versteckte Parameter enthalten und valide ist. Ist das nicht der Fall, wird die Anfrage abgewiesen.

Dieser versteckte Parameter ist während der Sitzung immer derselbe. Damit ergeben sich keine Probleme mit der Persistenz und Invalidierung, wie das in der derzeitigen Lösung geschieht. Die Verwendung mehrere Tabs ist daher völlig unproblematisch.

Außerdem wird automatisch jeder Request aus zurkünftigem Code abgesichert, solange die Entwickler sich an die Semantik der HTTP-Verben halten (GET/POST)—was allerdings bei Formularen als gegeben angenommen werden sollte.

Funktionsweise

Changed line 26 from:
to:

Anwendung

Changed lines 55-65 from:
  • Ganz wichtig:** Diese Methode darf ++NICHT++ aufgerufen werden, wenn es sich um ein GET-Formular handelt, da dann der Token in die URL wandert und damit über den Referer-Header an Dritt-Seiten übertragen wird. In diesem Fall wird der Schutz unwirksam. :no: :no: :no:
to:
  • Ganz wichtig:** Diese Methode darf ++NICHT++ aufgerufen werden, wenn es sich um ein GET-Formular handelt, da dann der Token in die URL wandert und damit über den Referer-Header an Dritt-Seiten übertragen wird. In diesem Fall wird der Schutz unwirksam. :no: :no: :no:

Schwierigkeiten

Schwierigkeiten ergeben sich folgende:

1.) Der versteckte Parameter darf niemals in eine URL gelangen, da dies alle Bemühungen über den Haufen werfen würde. Gerät der Token in die Hände eines Angreifers, kann dieser wieder beliebige Anfragen stellen. Dieses Problem gibt es aber natürlich mit der derzeitigen Lösung ebenso und kann mit geringem (Qualitätskontroll-)Aufwand verhindert werden.

2.) Es müssen alle Formulare gefunden werden, um ihnen den versteckten Parameter mitzugeben. Das ist mit ein den üblichen Tools (sed, grep…) relativ unproblematisch möglich.

3.) Die vorhandenen Tickets, die über GET-Requests versendet werden, müssen ummodelliert werden. Der Schwierigkeitsgrad ist noch nicht abzuschätzen, sollte aber erfahrungsgemäß im Rahmen liegen.

 
 
March 10, 2011, at 10:43 AM by mlunzena -
Added lines 1-32:

<TODO: (mlunzena) Wie funktioniert es?>

<TODO: (mlunzena) Was muss ich tun?>

Ich habe am Dienstag diesen StEP eingebaut und aus Zeitmangel noch nicht offiziell vorgestellt. Die API-Dokumentation befindet sich schon in der [Hilfe.]http://hilfe.studip.de/api/class_c_s_r_f_protection.html

++Was wurde getan?++

Um Stud.IP vor gefälschten Request zu schützen, muss nun jeder POST-Request (aber nicht Ajax) einen zusätzlichen Parameter "security_token" mitschicken, dessen Wert mit einem in der Session befindlichen verglichen wird. Um genau zu sein, wird für jeden Nutzer zu Beginn seiner Session ein 256-Bit-Token erzeugt und in der $_SESSION abgelegt. Jedes (!) Stud.IP-POST-Formular wurde um ein input[@type=hidden]-Element bereichert, dass diesen Token mitschickt. Sobald ein Request bei Stud.IP eintrifft, wird überprüft:

- ob es ein GET-Request ist, um dann die weitere Überprüfung abzubrechen - ob es ein XHR ist (also Ajax mit jQuery oder prototype), um dann die weitere Überprüfung abzubrechen - ob der mitgeschickte Parameter "security_token" existiert und mit dem Token aus der Session übereinstimmt

Diese Überprüfung findet automatisch am Ende von #page_open statt, in der Annahme, dass dann die notwendige Session existiert.

Fällt die Überprüfung negativ auf, wird ein Fehler (Status 403) gemeldet und die weitere Bearbeitung abgebrochen.

++ Was muss ich als Entwickler in Zukunft beachten? ++

Zukünftige Entwicklungen müssen beachten, dass form-Elemente, deren "method"-Attribut den Wert POST hat, ein weiteres, verstecktes input-Element benötigen, dessen Name "security_token" und dessen Wert dem Token aus der Session entspricht. Am einfachsten macht man es so:

[code] <form method="POST" … > <?= CSRFProtection::tokenTag() ?> … </form> [/code]

  • Ganz wichtig:** Diese Methode darf ++NICHT++ aufgerufen werden, wenn es sich um ein GET-Formular handelt, da dann der Token in die URL wandert und damit über den Referer-Header an Dritt-Seiten übertragen wird. In diesem Fall wird der Schutz unwirksam. :no: :no: :no:

 

 

Source: Basis-Wiki-Hilfe | Last change: April 01, 2011, at 11:41 PM, tthelen | Local view: Basis-Hilfe