Zum Inhalt springen

Services, Wiki-Artikel und Blog-Beiträge durchsuchen

↑↓NavigierenEnterÖffnenESCSchließen
OAuth 2.0 und OIDC Sicherheit: Häufige Fehler und wie man sie vermeidet - Cybersicherheit und digitaler Schutz
Offensive Security

OAuth 2.0 & OIDC Sicherheit: Häufige Fehler und Best Practices

OAuth 2.0 Sicherheitslücken: offene Redirects, CSRF, Authorization Code Interception und Best Practices für sichere OAuth-Implementierungen.

Vincent Heinen Abteilungsleiter Offensive Services
10 Min. Lesezeit
OSCP+ OSCP OSWP OSWA

TL;DR

OAuth 2.0 und OIDC sind de-facto-Standards für delegierte Autorisierung, enthalten aber häufige Implementierungsfehler mit kritischen Folgen. Typische Schwachstellen sind offene Redirect-URIs, fehlender CSRF-Schutz durch den state-Parameter, das Fehlen von PKCE für SPAs und mobile Apps sowie unsichere Token-Speicherung in localStorage. Access Tokens gehören in HTTPOnly-Cookies oder in Speicher ohne XSS-Zugriff. Refresh-Token-Rotation, kurze Token-Laufzeiten und Server-side Token-Invalidierung schließen die häufigsten Angriffsvektoren.

Diese Zusammenfassung wurde KI-gestützt erstellt (EU AI Act Art. 50).

Inhaltsverzeichnis (4 Abschnitte)

OAuth 2.0 ist überall: "Login with Google", "Verbinde mit GitHub", API-Zugriffe für Drittanbieter. Richtig implementiert ist OAuth sicher und bequem. Falsch implementiert entstehen kritische Sicherheitslücken - von Account-Takeover bis zu vollständiger API-Kompromittierung.

OAuth 2.0 Grundlagen - was tatsächlich passiert

OAuth 2.0 Rollen:

RolleBeschreibung
Resource OwnerDer User der Zugriffsrechte erteilt
ClientDie Anwendung die Zugriff beantragt (z.B. Kalender-App)
Authorization ServerStellt Tokens aus (Entra ID, Keycloak, Auth0)
Resource ServerAPI die mit Tokens geschützt ist (Google Calendar API)

Authorization Code Flow (Standard für Web-Apps):

  1. User klickt "Login mit Google"
  2. Client - Authorization Server:
GET /authorize?
  response_type=code&
  client_id=my-app-123&
  redirect_uri=https://myapp.com/callback&
  scope=email+calendar.read&
  state=RANDOM-CSRF-TOKEN
  1. User meldet sich an + genehmigt Zugriff
  2. Authorization Server - Client (Redirect):
GET https://myapp.com/callback?code=AUTH_CODE&state=RANDOM-CSRF-TOKEN
  1. Client - Authorization Server (Back-Channel):
POST /token
  code=AUTH_CODE&
  redirect_uri=https://myapp.com/callback&
  client_id=my-app-123&
  client_secret=MY-SECRET
  1. Authorization Server - Client:
{"access_token": "eyJ...", "expires_in": 3600}
  1. Client - Resource Server:
GET /calendar/events
Authorization: Bearer eyJ...

Warum Authorization Code Flow sicher ist:

  • Auth Code geht über Browser (unsicher), aber nutzlos ohne Client Secret
  • Access Token geht nur via Server-zu-Server (nie zum Browser)
  • state-Parameter: verhindert CSRF!

Die wichtigsten OAuth-Sicherheitsprobleme

Schwachstelle 1: Offene Weiterleitungen (Open Redirects)

Problem: Der Authorization Server erlaubt beliebige redirect_uri:

GET /authorize?
  response_type=code&
  client_id=my-app&
  redirect_uri=https://evil.com/steal
  &state=...

Ergebnis: Authorization Code wird an Angreifer gesendet! Auth Code + Client Secret = vollständiger Account-Takeover.

Schutz:

  • redirect_uri MUSS exakt vorregistriert sein
  • Authorization Server muss Exact-Match prüfen (kein Wildcard!)
  • Beispiel: nur https://myapp.com/callback erlaubt - NICHT https://myapp.com/*, NICHT https://*.myapp.com/callback

Schwachstelle 2: Fehlendes CSRF-Schutz (state-Parameter)

Problem: Angreifer erstellt speziell präparierten OAuth-Link mit &state=ATTACKER-CONTROLLED. Wenn der User seinen Account verbindet, wird der Angreifer-Account verbunden.

Schutz:

  • state-Parameter: kryptografisch zufällig, in Session gespeichert
  • Bei Callback: state aus URL = state in Session?
  • Wenn nicht gleich: Angriff erkannt, Prozess abbrechen!
// Implementierung (Node.js):
const state = crypto.randomBytes(32).toString('hex');
req.session.oauthState = state;
const authUrl = `${AUTH_SERVER}/authorize?...&state=${state}`;

// Callback:
if (req.query.state !== req.session.oauthState) {
  return res.status(400).json({error: 'CSRF detected!'});
}

Schwachstelle 3: Authorization Code Interception

Problem: Mobile Apps erhalten den Code via Custom URL Scheme (myapp://callback?code=AUTH_CODE). Eine andere App mit dem gleichen URL-Scheme kann den Code abfangen.

Schutz: PKCE (Proof Key for Code Exchange) - Pflicht für SPAs und Mobile!

code_verifier = 32 random bytes (geheimgehalten!)
code_challenge = BASE64URL(SHA256(code_verifier))
# 1. Start Authorization:
GET /authorize?
  ...&
  code_challenge=<SHA256_of_verifier>&
  code_challenge_method=S256

# 2. Token Request:
POST /token
  code=AUTH_CODE&
  code_verifier=ORIGINAL_VERIFIER

Abgefangener Auth Code ist nutzlos ohne code_verifier.

Schwachstelle 4: Unsichere Token-Speicherung

Problem: SPA speichert Access Token in localStorage - ein XSS-Angriff kann ihn auslesen.

Schutz:

  • Access Token: in memory-Variablen (nicht persistent)
  • Refresh Token: in HttpOnly Cookie (kein JS-Zugriff!)
  • SameSite=Strict: CSRF-Schutz für Cookies
// FALSCH - XSS-anfällig:
localStorage.setItem('access_token', token);

// RICHTIG - Token in Memory:
let accessToken = null;  // In-memory, verschwindet bei Reload

// Refresh Token: Server setzt HttpOnly Cookie:
res.cookie('refresh_token', refreshToken, {
  httpOnly: true,     // JavaScript kann nicht zugreifen
  secure: true,       // Nur HTTPS
  sameSite: 'strict', // CSRF-Schutz
  maxAge: 30 * 24 * 60 * 60 * 1000  // 30 Tage
});

Schwachstelle 5: Zu weite Scopes

Problem: App fordert alle Berechtigungen an - ein kompromittierter Token gibt Zugriff auf alles.

Schutz:

  • Minimal Scope: nur was aktuell benötigt wird
  • Incremental Authorization: Scope erst bei Bedarf anfordern
  • Scope Transparency: User sieht was App tatsächlich braucht
// Falsch: alles auf einmal
scope: 'email profile contacts calendar drive admin'

// Richtig: nur was benötigt wird
scope: 'email'  // Beim Login
// Später wenn User Kalender-Feature nutzt:
scope: 'email calendar.readonly'  // Minimal!

OpenID Connect (OIDC) Sicherheit

OIDC = OAuth 2.0 + Authentifizierung (Identität):

Zusätzlich zu Access Token gibt es ein ID Token (JWT). Das ID Token enthält: sub (User ID), email, name, issued at, expiry, nonce.

OIDC-Schwachstellen

1. ID Token nicht validiert:

Problem: App vertraut ID Token ohne Signatur-Prüfung - ein gefälschter ID Token kann einen anderen User vortäuschen.

Schutz:

  • IMMER signierte ID Tokens (RS256 oder ES256)
  • IMMER Signatur prüfen (mit JWKS des Authorization Server)
  • IMMER Expiry prüfen
  • IMMER Audience (aud) prüfen
# Python (Keycloak + python-jose):
from jose import jwks, jwt
keys = requests.get('https://keycloak/realm/certs').json()['keys']
payload = jwt.decode(
  id_token,
  keys,
  algorithms=['RS256'],
  audience='my-client-id',  # Pflicht!
  issuer='https://keycloak/realm'
)

2. Nonce-Replay:

Problem: Ohne nonce kann ein ID Token wiederverwendet werden. Schutz: nonce = random, in Session gespeichert - der nonce-Wert im ID Token muss dem in der Session entsprechen.

3. Implicit Flow (veraltet, unsicher):

Problem: Access + ID Token kommen direkt zum Browser via URL-Fragment - Token in URL = in Browser History, Logs, Referrer-Header. Nicht verwenden! Ersetzen durch Authorization Code Flow + PKCE.


JWT-Sicherheit (da OIDC JWTs nutzt)

JWT-Struktur: Header.Payload.Signature (base64-encoded, nicht verschlüsselt!).

JWT-Schwachstellen:

1. Algorithm Confusion (alg=none): Angriff: Header ändern zu {"alg": "none"}, Signature weglassen - unsichere Libraries akzeptieren das! Schutz: Algorithmus explizit festlegen beim Validieren, "none" niemals erlauben.

2. RS256 -> HS256 Switch: Angriff: RS256 (asymmetrisch) zu HS256 (symmetrisch) wechseln - der HS256-Schlüssel ist dann der öffentliche Schlüssel (den der Angreifer kennt!). Schutz: Algorithmus beim Validieren explizit auf RS256 fixieren.

3. Weak HS256 Secret: jwt.io Debugger + Brute-Force = geknacktes HS256 JWT. Schutz: HS256 Secret min. 256 Bit (32 Byte) zufällig; besser RS256/ES256 (asymmetrisch).

4. JWT ohne Expiry: Schutz: Immer exp Claim setzen, kurze Expiry (Access Token 15-60 Minuten).

OAuth für APIs - Client Credentials Flow

Machine-to-Machine Authentication (keine User-Interaktion):

Client Credentials Flow:

# Service A -> Authorization Server:
POST /token
  grant_type=client_credentials&
  client_id=service-a&
  client_secret=secret123&
  scope=api.read

# Authorization Server -> Service A:
{"access_token": "eyJ...", "expires_in": 3600}

# Service A -> Service B:
GET /internal-api/data
Authorization: Bearer eyJ...

Sicherheitsprobleme:

1. Client Secret Rotation:

  • Secrets müssen rotiert werden (mindestens jährlich!)
  • Rotation: neues Secret erstellen -> deployen -> altes deaktivieren
  • Secret im Vault (nicht in Konfigurationsdatei!)

2. Scope-Kontrolle:

  • client_id:service-a darf NUR /api/read
  • Nicht: admin-API, User-Daten anderer Services

3. Mutual TLS (mTLS) statt Client Secret:

  • Noch sicherer: Service A authentifiziert sich mit Zertifikat
  • Client Secret: shared secret (kann geleakt werden)
  • mTLS: privater Schlüssel verlässt Service nie
  • Kubernetes: Istio Service Mesh mit mTLS

Best Practices Zusammenfassung:

  • Authorization Code Flow + PKCE für alle Public Clients
  • state-Parameter IMMER (CSRF-Schutz)
  • redirect_uri: exaktes Matching, vorregistriert
  • Tokens: kurze Lifetime, Refresh Token in HttpOnly Cookie
  • Scopes: minimal, incremental authorization
  • ID Token: immer vollständig validieren (sig + aud + exp + nonce)
  • JWT: expliziter Algorithmus, kein "none", starkes Secret
  • Client Secrets: in Vault, rotieren, minimale Scope

OAuth-Implementierungsfehler sind in der OWASP API Security Top 10 prominent vertreten. AWARE7 analysiert OAuth/OIDC-Implementierungen im Rahmen von Penetrationstests und Web-Application-Security-Reviews.

API-Sicherheitstest anfragen | Penetrationstest Web-Applikationen

Nächster Schritt

Unsere zertifizierten Sicherheitsexperten beraten Sie zu den Themen aus diesem Artikel, unverbindlich und kostenlos.

Kostenlos · 30 Minuten · Unverbindlich

Artikel teilen

Über den Autor

Vincent Heinen
Vincent Heinen

Abteilungsleiter Offensive Services

E-Mail

M.Sc. IT-Sicherheit mit über 5 Jahren Erfahrung in offensiver Sicherheitsanalyse. Leitet die Durchführung von Penetrationstests mit Spezialisierung auf Web-Applikationen, Netzwerk-Infrastruktur, Reverse Engineering und Hardware-Sicherheit. Verantwortlich für mehrere Responsible Disclosures.

OSCP+ OSCP OSWP OSWA
Zertifiziert ISO 27001ISO 9001AZAV

Rufen Sie uns an

Mo-Fr, 8:00-17:00 Uhr - persönlich und unverbindlich.

0209 8830 6764
Jetzt anrufen