CSRF nutzt ein automatisches Verhalten des Browsers aus: Bei jeder Anfrage an eine Website schickt er deren Cookies mit, auch das Sitzungscookie. Eine fremde Seite kann also eine Anfrage an deine Website auslösen, und der Server erhält sie mit den Anmeldedaten des eingeloggten Benutzers. Nichts unterscheidet sie von einem bewussten Klick, es sei denn, die Website prüft, ob die Anfrage wirklich aus ihren eigenen Formularen stammt. MITRE führt diese Schwachstelle als CWE-352; man schreibt sie auch XSRF.
So funktioniert ein CSRF-Angriff
Der Angreifer bereitet eine Seite vor, die eine Anfrage an die Zielwebsite enthält: ein unsichtbares Bild, dessen URL eine Aktion auslöst, oder ein verstecktes Formular, das JavaScript automatisch absendet. Dann muss er das Opfer nur noch auf diese Seite locken, über einen Link in einer E-Mail, einem Kommentar oder einer Nachricht. Ist das Opfer gleichzeitig auf der Zielwebsite angemeldet, geht die Anfrage mit seiner Sitzung raus.

Wie OWASP betont, sieht der Angreifer die Antwort des Servers nicht. CSRF zielt deshalb auf Anfragen, die etwas verändern: die E-Mail-Adresse eines Kontos ändern, eine Einstellung umstellen, einen Benutzer anlegen, Inhalte löschen. Im WordPress-Adminbereich reichen solche Aktionen oft aus, um die Website zu übernehmen.
Die Rolle von SameSite-Cookies
Das Cookie-Attribut SameSite schränkt ein, wann Cookies von einer anderen Website aus mitgeschickt werden. Mit Strict begleitet das Cookie nur Anfragen, die von derselben Website kommen; mit Lax wird es auch bei einer Navigation auf oberster Ebene mit einer sicheren Methode gesendet, etwa bei einem einfachen GET-Link. MDN weist darauf hin, dass manche Browser Lax standardmäßig anwenden, wenn das Attribut fehlt. Das ist ein nützlicher, aber nur teilweiser Schutz: Eine Aktion, die per GET-Link ausgelöst wird, kommt trotzdem durch, und nicht alle Browser verhalten sich gleich. SameSite ergänzt Anti-CSRF-Tokens also, ersetzt sie aber nicht.
In WordPress: Nonces und Berechtigungsprüfung
WordPress schützt seine Formulare und Aktionslinks mit Nonces: Tokens, die an den Benutzer, seine Sitzung und die angeforderte Aktion gebunden sind und die eine fremde Website nicht erraten kann. Ihre Gültigkeit beträgt standardmäßig 24 Stunden, aufgeteilt in zwei Zeitfenster von je 12 Stunden. Ein Plugin, das eigene Aktionen hinzufügt, muss sie ebenfalls verwenden:
// Im Formular
wp_nonce_field( 'myplugin_save', 'myplugin_nonce' );
// Bei der Verarbeitung
check_admin_referer( 'myplugin_save', 'myplugin_nonce' );
if ( ! current_user_can( 'manage_options' ) ) {
wp_die( 'Zugriff verweigert' );
}
wp_nonce_field()undwp_nonce_url()fügen das Token in ein Formular oder eine URL ein;check_admin_referer()prüft es im Adminbereich,check_ajax_referer()bei einer AJAX-Anfrage,wp_verify_nonce()überall sonst;current_user_can()bleibt Pflicht: Die WordPress-Dokumentation stellt klar, dass eine Nonce nicht zur Authentifizierung oder Zugriffskontrolle gedacht ist.
So schützt du deine Website als Betreiber
Fehlende Nonces sind in Plugins immer noch häufig: CSRF gehört zu den Schwachstellenkategorien, die regelmäßig gemeldet werden, wie die Zahlen zu Schwachstellen in WordPress-Plugins zeigen. Als Betreiber helfen dir einfache Gewohnheiten: Updates einspielen, während einer Admin-Sitzung keine unbekannten Links anklicken, dich nach der Arbeit an der Website abmelden und nicht unnötig viele Administratorkonten anlegen. Weder WP Masquerade noch irgendeine Einstellung im Dashboard behebt eine fehlende Nonce in einem Plugin: Das schafft nur ein Update des Plugins.
Häufige Fehler
- Die Nonce prüfen, aber nicht die Berechtigungen: Ein angemeldeter Abonnent, der eine gültige Nonce von einer für ihn zugänglichen Seite abgreift, kann dann eine Aktion aufrufen, die für Administratoren gedacht ist. Das öffnet IDOR und anderen Lücken in der Zugriffskontrolle die Tür.
- Daten per einfacher GET-Anfrage ändern, die selbst mit
SameSite=Lax-Cookies durchgeht. - Vergessen, dass eine Cross-Site-Scripting-Lücke den Schutz aushebelt: Ein Skript, das in der Seite läuft, liest die darin enthaltenen Nonces einfach aus.
- CSRF mit Clickjacking verwechseln: Beim Clickjacking klickt das Opfer auf deine echte Seite, die in einem unsichtbaren Frame angezeigt wird, und das verhindert eine Nonce nicht.