Teil 7 – Exploiting OAuth: CSRF in OAuth

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 und state:
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.

Kommentare

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert