Sicherheit · 3 Min. Lesezeit ·

Was in einem JWT steckt und warum Dekodieren kein Prüfen ist

Ein JSON Web Token sieht aus wie Zeichensalat, aber jeder kann es lesen. Was seine drei Teile enthalten und welcher Fehler zu Sicherheitslücken führt.

Ein JWT (JSON Web Token) ist die lange Zeichenkette, die dich in vielen Web-Apps und APIs angemeldet hält. Es wirkt verschlüsselt, ist es aber meistens nicht: Wer das Token hat, kann lesen, was drinsteht.

Drei Teile, durch Punkte getrennt

eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiI0MiJ9.3q2-7w…
└ header ──────────┘ └ payload ───────┘ └ signature

Der Header sagt, wie das Token signiert ist, zum Beispiel HS256 oder RS256. Der Payload enthält die Claims: wer der Nutzer ist (sub), wann das Token ausgestellt wurde (iat) und wann es abläuft (exp), dazu alles, was die App ergänzt, etwa Rollen. Beides ist JSON in base64url-Kodierung, und das ist eine Kodierung, keine Verschlüsselung.

Entscheidend ist die Signatur

Der dritte Teil ist eine Signatur über die ersten beiden, erstellt mit einem Geheimnis oder einem privaten Schlüssel. Nur ein Server mit dem richtigen Schlüssel kann sie prüfen. Ändert jemand auch nur ein Zeichen im Payload, etwa die Rolle von user auf admin, passt die Signatur nicht mehr.

Dekodieren ist nicht Prüfen

Ein Token, das sich sauber dekodieren lässt, sagt dir, was es behauptet, nicht, ob es stimmt. Dein Backend muss die Signatur mit dem Schlüssel prüfen, Tokens mit abgelaufenem exp ablehnen und nur die erwarteten Algorithmen akzeptieren, niemals „none“. JWT-Bibliotheken erledigen das für dich; es wegzulassen ist eine klassische Schwachstelle.

Praktische Regeln

Leg keine Geheimnisse wie Passwörter in den Payload, denn er ist lesbar. Halte Ablaufzeiten kurz. Behandle ein Token wie ein Passwort, solange es gültig ist: Wer es kopiert, kann es bis zum Ablauf benutzen.

Wo ein Token im Browser liegen sollte

Alles in localStorage kann jedes Skript auf der Seite lesen, ein einziger Cross-Site-Scripting-Fehler (XSS) kann den Token also preisgeben. Ein HttpOnly-Cookie ist für JavaScript gar nicht lesbar, das beseitigt dieses Risiko; kombiniere es mit den Attributen Secure und SameSite und einem Schutz gegen Cross-Site Request Forgery (CSRF). Eine perfekte Lösung gibt es nicht, aber für Session-Tokens sind HttpOnly-Cookies die sicherere Standardwahl.

Ablauf und Refresh-Tokens

Ein JWT lässt sich nicht von selbst „abmelden“: Er bleibt bis zu seiner exp-Zeit gültig, es sei denn, der Server führt eine Sperrliste. Deshalb leben Access-Tokens meist Minuten, nicht Tage. Ein langlebigerer Refresh-Token, der sorgfältiger aufbewahrt und vom Server geprüft wird, holt einen neuen Access-Token, wenn der alte abläuft.

Die üblichen Claims auf einen Blick

iss  Aussteller     wer den Token erstellt hat
sub  Subjekt        der Nutzer oder Client, um den es geht
aud  Zielgruppe     welcher Dienst ihn akzeptieren soll
exp  Ablauf         Unix-Zeit, ab der er ungültig ist
nbf  nicht vor      Unix-Zeit, vor der er ungültig ist
iat  ausgestellt    Unix-Zeit seiner Erstellung

Die Zeit-Claims sind Unix-Zeitstempel in Sekunden. Ein Server muss neben exp auch aud prüfen: Ein gültiger Token für einen Dienst sollte von einem anderen nicht akzeptiert werden.

Ein Token lesen

Der JWT-Decoder von 4Dev zerlegt ein Token in seine Teile und zeigt Header und Payload als lesbares JSON. Er dekodiert nur und prüft die Signatur nicht. Das Token wird zum Dekodieren an den 4Dev-Server gesendet und weder protokolliert noch gespeichert; füge trotzdem keine echten Produktions-Tokens ein und widerrufe jedes Token, das du für kompromittiert hältst.

JWT-Decoder öffnen

LinkedInXFacebook