Was ist Cross-Site-Request-Forgery (CSRF)?

Cross-Site-Request-Forgery ist ein ziemlicher Zungenbrecher, aber dennoch ein wichtiges Thema, wenn es um Sicherheit im Web geht. Wie zuvor beim Cross-Site-Scripting (XSS) möchte ich euch einen Einblick geben, was das Problem genau ist und was wir dagegen tun können.

CSRF: Was ist das eigentlich?

Zum besseren Verständnis dröseln wir Cross-Site-Request-Forgery mal in seine Bestandteile auf.
Cross-Site: Also von einer anderen Webseite, auf die wir keinen Einfluss haben.
Request-Forgery: Es wird eine Anfrage an eure Webseite gefälscht, so dass es für euch so aussieht als käme sie von einem legitimen User.

Was ist das Angriffs-Szenario?

Im Gegensatz zum XSS findet der Angriff nicht auf eurer Webseite statt, sondern baut darauf, dass ein Besucher der präparierten Seite rein zufällig ebenfalls ein Kunde von euch ist und er bei euch aktuell eingeloggt ist.

Also nehmen wir zum Beispiel Facebook. Ihr seid möglicherweise gerade dort eingeloggt (z. B. in einem anderen Browser-Tab). Ich könnte jetzt also hier auf der Seite einen Code-Schnipsel platzieren, der ein POST-Request an Facebook schickt, das identisch zum Submit des „Beitrag-Posten“-Formulars ist. Euer Browser hängt automatisch die richtigen Cookies an – das Formular geht schließlich an facebook.com und aus Sicht des Browsers ist daran nichts verdächtig.
Ohne CSRF-Schutz seitens Facebook hättet ihr jetzt etwas gepostet, das ihr so sicher nicht wolltet.

Was tun wir gegen CSRF?

Da der Angriff nicht auf eurer Seite stattfindet und alle beteiligten Aktionen völlig normales Verhalten sind, könnt ihr es nicht verhindern. Ihr müsst also erkennen was gewünschte Daten sind und was nicht.

Hier kommt das CSRF-Token ins Spiel. Es ist nichts weiter als ein verstecktes Eingabefeld mit einem zufällig generierten Code, den ihr zusätzlich in der Session des Nutzers speichert. Kommen jetzt die Formulardaten am Server an, vergleicht ihr die beiden Werte. Stimmen sie überein, hat der Nutzer sie tatsächlich auf eurer Seite abgeschickt. Andernfalls war es CSRF.

Was ist beim CSRF-Token zu beachten?

Wichtig ist, dass euer Formular nicht inklusive Token simuliert werden kann. Euer Token muss also auf jeden Fall für jeden Nutzer anders und nicht vorhersehbar sein. Sendet ihr eure Formulare nicht per AJAX könnt ihr auch bei jedem Seitenaufruf ein neues Token generieren.

Sorgt dafür, dass euer CSRF-Token hinreichend lang und zufällig ist.

Beispiel-Code

Irgendwo in eurem Controller erzeugt ihr ein Token:

Das gebt ihr dann als Teil des Formulars aus:

Und schließlich die beiden gegeneinander prüfen, wenn ihr das Formular geschickt bekommt:

Wenn ihr anschließend noch das Token aus der Session löscht und ein neues erzeugt, könnt ihr als Bonus noch verhindern, dass eure Nutzer Formulare mehrfach abschicken.


Hier geht’s zu den anderen Artikeln zum Thema Sicherheitsrisiken einer Webanwendung.