JWT-Tokens erklärt: Aufbau, Sicherheit und häufige Fehler
Verstehe, wie JSON Web Tokens funktionieren, was in ihnen steckt und welche Sicherheitsfallen Entwickler in der Praxis immer wieder tappen.
JSON Web Tokens (JWTs) sind allgegenwärtig – sie treiben die Authentifizierung in SPAs, mobilen Apps und Microservice-Architekturen weltweit an. Dennoch gehören sie zu den am häufigsten missverstandenen Sicherheitselementen in der Webentwicklung. Fehler dabei können Authentifizierungsumgehung, Rechteausweitung oder vollständige Kontoübernahme bedeuten.
Was ist ein JWT?
Ein JWT ist ein kompakter, URL-sicherer String, der eine Reihe von Claims kodiert – Aussagen über einen Benutzer oder eine Sitzung. Er sieht so aus:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
Es handelt sich um drei Base64URL-kodierte Segmente, die durch Punkte getrennt sind:
- Header – Algorithmus und Token-Typ
- Payload – die Claims (Benutzerdaten)
- Signature – kryptografischer Integritätsnachweis
Füge einen beliebigen JWT in unseren JWT Decoder ein, um alle drei Teile sofort zu prüfen – ohne einen externen Server zu kontaktieren.
Aufbau eines JWT
Header
{
"alg": "HS256",
"typ": "JWT"
}
alg gibt den Signierungsalgorithmus an. Gängige Werte:
HS256— HMAC mit SHA-256 (symmetrisch, einzelnes Secret)RS256— RSA mit SHA-256 (asymmetrisch, öffentlicher/privater Schlüssel)ES256— ECDSA mit SHA-256 (asymmetrisch, kleinere Schlüssel)
Payload
{
"sub": "user_abc123",
"email": "alice@example.com",
"role": "admin",
"iat": 1711670400,
"exp": 1711756800
}
Standardmäßig registrierte Claims:
| Claim | Bedeutung |
|---|---|
sub |
Subject (über wen das Token ausgestellt ist) |
iss |
Issuer (wer das Token erstellt hat) |
aud |
Audience (wer es akzeptieren soll) |
exp |
Ablaufzeit (Unix-Timestamp) |
iat |
Ausstellungszeitpunkt (Unix-Timestamp) |
nbf |
Not before (vor diesem Zeitpunkt nicht akzeptieren) |
Signature
Für HS256:
HMAC-SHA256(base64url(header) + "." + base64url(payload), secret)
Die Signatur beweist, dass das Token nicht manipuliert wurde. Der Payload ist NICHT verschlüsselt – er ist lediglich kodiert. Jeder kann ihn lesen.
Speichere niemals sensible Daten wie Passwörter oder Kreditkartennummern im JWT-Payload.
HS256 vs. RS256: Was ist zu bevorzugen?
HS256 verwendet ein einzelnes gemeinsames Secret. Jeder Dienst, der Tokens verifizieren muss, benötigt dasselbe Secret. Einfach für Monolithen, aber gefährlich in Multi-Service-Architekturen – wird ein Dienst kompromittiert, kann ein Angreifer Tokens fälschen.
RS256 verwendet asymmetrische Schlüssel. Der Auth-Server signiert mit einem privaten Schlüssel; alle anderen Dienste verifizieren mit dem öffentlichen Schlüssel. Die Kompromittierung eines Consumer-Dienstes gibt einem Angreifer nicht die Möglichkeit, Tokens zu fälschen. Bevorzuge RS256 für jedes System mit mehreren Diensten.
Die alg: none-Schwachstelle
Einer der berüchtigtsten JWT-Angriffe. Einige ältere Bibliotheken akzeptierten ein Token mit "alg": "none" und ohne Signatur – und behandelten es als gültig. Ein Angreifer konnte folgendes konstruieren:
{ "alg": "none" }
mit einem beliebigen Payload und die Authentifizierung vollständig umgehen.
Lösung: Gib in deiner JWT-Bibliothek immer explizit die erlaubten Algorithmen an. Akzeptiere niemals none.
// ❌ Gefährlich
jwt.verify(token, secret);
// ✅ Sicher — akzeptiert nur HS256
jwt.verify(token, secret, { algorithms: ["HS256"] });
Algorithm-Confusion-Angriff
Eine weitere kritische Schwachstelle: Erkennt deine Bibliothek den Algorithmus automatisch aus dem Header, kann ein Angreifer RS256 in HS256 ändern und das Token mit dem öffentlichen Schlüssel als HMAC-Secret signieren (der per Definition öffentlich ist).
Lösung: Hardcode stets den erwarteten Algorithmus. Vertraue niemals dem alg-Header.
Token-Speicherung: Wo JWTs aufbewahren?
| Speicherort | XSS-Risiko | CSRF-Risiko | Hinweise |
|---|---|---|---|
localStorage |
Hoch | Keines | Für jedes JS auf der Seite zugänglich |
sessionStorage |
Hoch | Keines | Wird beim Schließen des Tabs gelöscht |
| HTTP-only Cookie | Keines | Mittel | Beste Wahl für Web-Apps; SameSite=Strict verwenden |
| Speicher (Variable) | Niedrig | Keines | Geht beim Neuladen verloren; für SPAs |
Für Webanwendungen sind HTTP-only Cookies mit SameSite=Strict die sicherste Option. Für native Apps sind sichere Speicher-APIs (Keychain, Keystore) angemessen.
Ablauf und Refresh Tokens
Kurzlebige Access Tokens (5–15 Minuten) in Kombination mit langlebigen Refresh Tokens ist das Standardmuster:
- Benutzer meldet sich an → Server stellt Access Token aus (15 Min.) + Refresh Token (7 Tage, in DB gespeichert)
- Client verwendet Access Token für API-Aufrufe
- Nach Ablauf des Access Tokens sendet der Client das Refresh Token → erhält ein neues Access Token
- Beim Abmelden das Refresh Token in der Datenbank ungültig machen
Dies begrenzt das Schadenspotenzial, falls ein Access Token gestohlen wird.
JWTs widerrufen
JWTs sind zustandslos – einmal ausgestellt, sind sie bis zum Ablauf gültig. Das ist ein Kompromiss. Optionen zum vorzeitigen Widerruf:
- Blocklist – ungültige JTI-Werte (JWT ID) in Redis speichern und bei jeder Anfrage prüfen.
- Kurze Ablaufzeit – 5-Minuten-Tokens begrenzen den Schaden.
- Refresh Token Rotation – Wiederverwendung eines rotierten Tokens als Hinweis auf Diebstahl erkennen.
Debugging mit dem JWT Decoder
Beim Debuggen von Auth-Problemen nutze unseren JWT Decoder, um:
- Den vollständigen Payload ohne Code zu prüfen
- Ablaufzeitstempel in menschenlesbarer Form zu überprüfen
- Den verwendeten Algorithmus zu verifizieren
- Unerwartete oder fehlende Claims zu erkennen
Die gesamte Dekodierung findet lokal in deinem Browser statt – Tokens verlassen nie deinen Rechner.
JWT-Sicherheits-Checkliste
- RS256 oder ES256 für Multi-Service-Architekturen verwenden
- Erlaubte Algorithmen in der Bibliothek explizit angeben
-
exp-,iss- undaud-Claims bei jeder Anfrage validieren - Tokens in HTTP-only Cookies für Web-Apps speichern
- Kurze Access-Token-Laufzeiten verwenden (15 Min. oder weniger)
- Refresh Token Rotation mit Wiederverwendungserkennung implementieren
- Keine sensiblen Daten in den Payload schreiben
- HTTPS überall einsetzen – ein Token im Klartext ist so gut wie keine Authentifizierung
JWTs sind leistungsstark und praktisch, aber nur so sicher wie ihre Implementierung. Wer den Aufbau versteht und die Angriffsvektoren kennt, baut eine solide Authentifizierungsschicht.