JSON Web Token Sicherheit: Häufige Schwachstellen und Lösungen
JWTs sind der De-facto-Standard für API-Authentifizierung, aber ihre scheinbare Einfachheit verbirgt echte Sicherheitsfallen. Fehlkonfigurierte JWTs haben zu Authentifizierungsumgehungen, Rechteeskalation und Datenlecks geführt. Dieser Leitfaden behandelt die kritischsten Schwachstellen und wie man sie verhindert.
JWT-Struktur im Überblick
Ein JWT besteht aus drei Base64URL-kodierten Teilen, getrennt durch Punkte:
eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjMiLCJyb2xlIjoiYWRtaW4ifQ.signature
- Header: Algorithmus und Token-Typ
- Payload: Claims (Benutzerdaten, Ablaufzeit usw.)
- Signatur: Kryptografische Verifizierung
Überprüfen Sie die JWT-Struktur mit unserem JWT Encoder/Decoder.
Für ein grundlegendes Verständnis der JWT-Struktur siehe unseren Leitfaden JWT Tokens erklärt.
Kritische Schwachstellen
1. Algorithmenverwechslungsangriff
Die gefährlichste JWT-Schwachstelle. Wenn ein Server den alg-Header aus dem Token ohne Validierung akzeptiert, kann ein Angreifer:
Angriff: Den Algorithmus von RS256 (asymmetrisch) auf HS256 (symmetrisch) ändern und das gefälschte Token mit dem öffentlichen Schlüssel des Servers signieren:
// Gefälschtes Token des Angreifers
header: { "alg": "HS256", "typ": "JWT" }
payload: { "sub": "admin", "role": "superadmin" }
// Signiert mit dem ÖFFENTLICHEN Schlüssel des Servers als HMAC-Secret
Wenn der Server HS256-Tokens mit dem öffentlichen Schlüssel als Secret verifiziert, besteht das gefälschte Token die Verifizierung.
Lösung: Den erwarteten Algorithmus immer explizit angeben:
// FALSCH - akzeptiert jeden Algorithmus, den das Token angibt
jwt.verify(token, key);
// RICHTIG - bestimmten Algorithmus erzwingen
jwt.verify(token, key, { algorithms: ['RS256'] });
2. None-Algorithmus-Angriff
Einige Bibliotheken akzeptieren "alg": "none" — ein Token ohne Signatur:
// Gefälschtes Token ohne Signatur
header: { "alg": "none", "typ": "JWT" }
payload: { "sub": "admin", "role": "superadmin" }
signature: "" // leer
Lösung: Den none-Algorithmus in Produktion niemals erlauben. Erlaubte Algorithmen explizit auf eine Whitelist setzen.
3. Schwache Signiergeheimnisse
HMAC-basierte JWTs (HS256/HS384/HS512) sind nur so stark wie das Secret:
// SCHRECKLICH - kann in Sekunden per Brute-Force geknackt werden
secret = "password123"
// SCHWACH - anfällig für Wörterbuchangriffe
secret = "my-jwt-secret"
// STARK - 256+ Bit Zufälligkeit
secret = "a3f2b8c9d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0"
Lösung: Mindestens 256 Bit kryptografischer Zufälligkeit für HMAC-Secrets verwenden. Besser noch: Asymmetrische Schlüssel verwenden (RS256, ES256), bei denen der Signierschlüssel nie geteilt werden muss.
4. Fehlende Ablaufzeit
Tokens ohne Ablaufzeit laufen nie ab — ein gestohlenes Token gewährt dauerhaften Zugang:
// FALSCH - keine Ablaufzeit
{ "sub": "user123", "role": "admin" }
// RICHTIG - kurze Ablaufzeit
{
"sub": "user123",
"role": "admin",
"exp": 1705312800,
"iat": 1705309200,
"nbf": 1705309200
}
Best Practice: Access-Tokens laufen in 15-60 Minuten ab. Verwenden Sie Refresh-Tokens (sicher gespeichert) für lange Sitzungen.
5. Sensible Daten im Payload
JWT-Payloads sind Base64URL-kodiert, nicht verschlüsselt. Jeder kann sie dekodieren:
echo "eyJzdWIiOiIxMjMiLCJyb2xlIjoiYWRtaW4ifQ" | base64 -d
# {"sub":"123","role":"admin"}
Niemals einschließen: Passwörter, API-Schlüssel, Kreditkartennummern, persönliche Daten (Sozialversicherungsnummern, Krankenakten) oder irgendein Geheimnis in JWT-Payloads.
6. Token-Speicherung (XSS vs CSRF)
| Speicherung | XSS-anfällig | CSRF-anfällig |
|---|---|---|
| localStorage | Ja | Nein |
| Cookie (ohne Flags) | Ja | Ja |
| HttpOnly Cookie | Nein | Ja |
| HttpOnly + SameSite Cookie | Nein | Nein |
Empfohlen: JWTs in HttpOnly, Secure, SameSite=Strict Cookies speichern. Dies verhindert JavaScript-Zugriff (XSS-Schutz) und Cross-Site-Anfragen (CSRF-Schutz).
Set-Cookie: token=eyJ...; HttpOnly; Secure; SameSite=Strict; Path=/; Max-Age=3600
Sicherheits-Checkliste
- Algorithmen explizit angeben — niemals aus dem Token-Header akzeptieren
none-Algorithmus ablehnen — immer eine Signatur verlangen- Starke Secrets verwenden — 256+ Bit für HMAC, 2048+ Bit für RSA
- Kurze Ablaufzeit setzen — 15-60 Minuten für Access-Tokens
- Alle Claims validieren —
exp,iss,aud,nbf - In HttpOnly-Cookies speichern — nicht in localStorage
- Secrets regelmäßig rotieren — Schlüsselrotation einplanen
- Niemals sensible Daten im Payload speichern
- Asymmetrische Schlüssel verwenden für verteilte Systeme (RS256 oder ES256)
- Token-Widerruf implementieren — Blacklist oder kurze Ablaufzeit + Refresh-Tokens
Asymmetrische vs. symmetrische Signierung
| Aspekt | HS256 (Symmetrisch) | RS256 (Asymmetrisch) |
|---|---|---|
| Schlüssel | Geteiltes Secret | Privat-/Öffentliches Schlüsselpaar |
| Wer kann signieren | Jeder mit dem Secret | Nur der Inhaber des privaten Schlüssels |
| Wer kann verifizieren | Jeder mit dem Secret | Jeder mit dem öffentlichen Schlüssel |
| Schlüsselverteilung | Secret muss sicher geteilt werden | Nur der öffentliche Schlüssel wird geteilt |
| Leistung | Schneller | Langsamer |
| Ideal für | Einzelner Dienst | Microservices, verteilte Systeme |
Empfehlung: Verwenden Sie ES256 (ECDSA) für neue Anwendungen — es bietet asymmetrische Sicherheit mit einer Leistung nahe an HMAC.
Token-Widerrufsstrategien
JWTs sind konzeptionell zustandslos — es gibt keine eingebaute Möglichkeit, sie zu widerrufen. Strategien:
- Kurze Ablaufzeit: Wenn Tokens in 15 Minuten ablaufen, ist das Zeitfenster eines gestohlenen Tokens begrenzt
- Refresh-Token-Rotation: Bei jeder Verwendung ein neues Refresh-Token ausgeben; wenn ein Refresh-Token zweimal verwendet wird, alle Tokens widerrufen
- Blacklist: Widerrufene Token-IDs (jti-Claims) speichern und bei jeder Anfrage prüfen
- Token-Versionierung: Eine Versionsnummer in die Claims aufnehmen; die Version des Benutzers beim Abmelden erhöhen
FAQ
Sollte ich JWT oder Session-Cookies für die Authentifizierung verwenden?
Session-Cookies sind einfacher und sicherer für traditionelle Webanwendungen — der Server kontrolliert den Sitzungslebenszyklus, und der Widerruf ist sofort. JWTs sind besser für zustandslose APIs, Microservices und mobile Apps, bei denen serverseitige Sitzungsspeicherung unpraktisch ist. Wenn Sie sich für JWTs entscheiden, implementieren Sie die Sicherheitsmaßnahmen in diesem Leitfaden.
Was ist die ideale JWT-Ablaufzeit?
Für Access-Tokens: 15-60 Minuten. Kürzer ist sicherer, erfordert aber häufigere Aktualisierung. Für Refresh-Tokens: 1-30 Tage, gespeichert in HttpOnly-Cookies. Für Einmalverwendungs-Tokens (E-Mail-Verifizierung, Passwort-Zurücksetzung): 1-24 Stunden.
Verwandte Ressourcen
- JWT Encoder/Decoder — JWTs sicher inspizieren und dekodieren
- JWT Tokens erklärt — JWT-Struktur und -Ablauf verstehen
- Passwort-Entropie erklärt — Stärke von JWT-Signiergeheimnissen
🛠️ Jetzt ausprobieren: JWT Encoder/Decoder — 100% kostenlos, alles wird in Ihrem Browser verarbeitet. Keine Daten hochgeladen.