Warum CSRF bei OAuth ein Problem ist
CSRF (Cross-Site Request Forgery) ist ein alter Bekannter in der Websicherheit. Normalerweise bedeutet es: Ein Angreifer bringt einen Benutzer dazu, unbeabsichtigt eine Aktion in einer Webanwendung auszuführen – etwa eine Überweisung oder das Ändern eines Passworts.
In OAuth ist CSRF besonders gefährlich, weil es hier nicht nur um einzelne Aktionen geht, sondern um den gesamten Login- oder Autorisierungsprozess. Wenn ein Angreifer diesen Prozess manipuliert, kann er den Benutzer unbemerkt mit dem Account des Angreifers verbinden.
Das Einfallstor ist fast immer ein fehlender oder falsch genutzter state
-Parameter.
Der state
-Parameter – Schutz vor CSRF
Im OAuth-Standard wird empfohlen (und seit OAuth 2.1 verlangt), dass Clients einen zufälligen state
-Wert in der Anfrage mitsenden:
GET https://accounts.google.com/o/oauth2/v2/auth?
response_type=code
&client_id=123
&redirect_uri=https://app.example.com/callback
&scope=email
&state=abc123XYZ
- Der Client speichert
abc123XYZ
lokal (z. B. in der Session). - Nach dem Login leitet der Autorisierungs-Server den Benutzer zurück an die Redirect URI – inkl.
code
undstate
:
https://app.example.com/callback?code=CODE123&state=abc123XYZ
- Der Client prüft, ob der Wert identisch ist.
- Nur dann akzeptiert er den Flow.
👉 Ohne state
weiß die Anwendung nicht, ob die Antwort zu einer legitimen Anfrage gehört – oder von einem Angreifer stammt.
Angriffsablauf: CSRF in OAuth
Schritt 1 – Angreifer startet selbst einen OAuth-Flow
Der Angreifer klickt selbst auf „Login mit Google“ in der Ziel-App.
- Er meldet sich mit seinem eigenen Google-Konto an.
- Er bekommt am Ende einen gültigen Autorisierungscode.
Beispiel:
https://app.example.com/callback?code=ATTACKERCODE
Schritt 2 – Angreifer baut eine präparierte URL
Er nimmt den Code aus seinem eigenen Flow und erstellt eine URL, die den Benutzer dorthin schickt:
https://app.example.com/callback?code=ATTACKERCODE
Schritt 3 – Opfer klickt auf den Link
Das Opfer besucht z. B. eine manipulierte Webseite oder klickt auf eine Phishing-Mail.
- Der Browser des Opfers folgt dem Link.
- Die Ziel-App denkt: „Ah, da kommt ein gültiger OAuth-Code von Google.“
- Sie tauscht den Code gegen ein Token ein.
Schritt 4 – Ergebnis: Account-Kopplung
Die Anwendung glaubt nun, dass das Opfer sich mit Google eingeloggt hat. In Wirklichkeit ist das Konto von Angreifer-Google verbunden.
Konsequenz:
- Das Opfer erstellt Daten, die im Account des Angreifers landen.
- Der Angreifer kann das Opfer später „hijacken“, indem er sich einfach in seinen eigenen Account einloggt.
Beispiel-Szenario: Social Media Login
- Eine App erlaubt Login mit Facebook.
state
wird nicht genutzt.- Angreifer startet selbst einen Flow, kopiert den Code.
- Opfer klickt auf präparierten Link.
- Ergebnis: Opfer-Account ist mit dem Facebook-Account des Angreifers verbunden.
👉 Ab jetzt kann der Angreifer sich jederzeit bei der App einloggen – über sein eigenes Facebook-Konto.
Weitere Angriffsmöglichkeiten
Session-Fixation
Manche Anwendungen speichern den state
-Wert, validieren ihn aber nicht korrekt.
- Angreifer setzt vorher einen bekannten Wert.
- Später kann er denselben Wert im Redirect nutzen und den Flow übernehmen.
Kombination mit offenen Redirects
Wenn die Redirect-URI offen ist, kann ein Angreifer nicht nur den Flow hijacken, sondern das Token gleich auf seine eigene Domain umleiten.
Warum dieser Angriff so tückisch ist
- Er funktioniert ohne Passwortdiebstahl.
- Opfer merken oft nichts – sie sind „ganz normal“ eingeloggt.
- Entwickler unterschätzen den Wert von
state
und lassen ihn oft weg.
Für Bug-Bounty-Hunter ist es ein beliebtes Ziel: Fehlender state
→ Account Takeover.
Schutzmaßnahmen gegen CSRF in OAuth
1. Immer state
nutzen
- Für jede OAuth-Anfrage muss ein neuer, zufälliger Wert erzeugt werden.
- Der Wert muss auf Serverseite gespeichert und bei der Rückkehr überprüft werden.
2. Komplexe Werte
state
sollte ein zufälliger, kryptografisch sicherer Wert sein (z. B. 128 Bit).- Keine vorhersehbaren IDs oder Session-IDs.
3. Nonce bei OpenID Connect
OIDC ergänzt zusätzlich einen nonce
-Parameter für ID Tokens.
- Verhindert Wiederverwendung alter Tokens.
4. PKCE als Ergänzung
PKCE schützt vor Code-Diebstahl, ersetzt aber nicht den state
.
- Beide zusammen bieten Schutz gegen Replay und CSRF.
5. Strenge Redirect-URIs
Selbst mit state
ist es gefährlich, wenn Redirects offen sind.
- Immer feste URIs whitelisten.
- Keine dynamischen Parameter erlauben.
Schreibe einen Kommentar