ToolDeck

JWT

2 Tools

Grundlagen der Web-Sicherheit

Web-Sicherheit ist die Praxis, Webanwendungen und APIs vor unbefugtem Zugriff, Datenverletzungen und Angriffen zu schützen. Moderne Anwendungen verwenden Authentifizierung, Autorisierung und Kryptographie. Dabei bilden standardisierte Token-Formate wie JWT die Brücke zwischen dezentralen Diensten, ohne dass für jede Anfrage eine zentrale Sitzungsdatenbank abgefragt werden muss.

JSON Web Tokens (JWT) sind der dominante zustandslose Authentifizierungsmechanismus in der modernen Webentwicklung. Das Verständnis ihrer Struktur, Signaturalgorithmen und Schwachstellen ist grundlegend für den Aufbau sicherer APIs und Anwendungen. In Microservices-Umgebungen ermöglichen JWTs es jedem Dienst, Identität und Berechtigungen eigenständig zu prüfen, ohne Anfragen an einen zentralen Auth-Server weiterleiten zu müssen.

JSON Web Tokens (JWT)

Ein JWT ist eine kompakte, URL-sichere Methode, Ansprüche zwischen zwei Parteien darzustellen. Er besteht aus drei Base64url-kodierten Teilen, getrennt durch Punkte. Da die Signatur den gesamten Token abdeckt, kann die Gültigkeit eines JWT ohne Datenbankabfrage geprüft werden — der Empfänger benötigt lediglich den öffentlichen Schlüssel oder das gemeinsame Geheimnis.

Die drei Teile eines JWT

Header

Enthält Metadaten über den Token: den Signaturalgorithmus (alg) und den Token-Typ (typ). Die Algorithmuswahl im Header beeinflusst die gesamte Sicherheit des Tokens — ein schwacher oder fehlender Algorithmus macht die Signatur wertlos.

Kodiert
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
Dekodiert
{
  "alg": "HS256",
  "typ": "JWT"
}
Payload

Enthält die Claims: Aussagen über den Benutzer und zusätzliche Metadaten. Die Payload-Daten sind NICHT verschlüsselt, nur signiert. Das bedeutet, dass jeder, der den Token abfängt, die Payload lesen kann — sensible Daten wie Passwörter dürfen daher niemals in der Payload gespeichert werden.

Kodiert
eyJzdWIiOiJ1c2VyXzEyMyIsInJvbGUiOiJhZG1pbiIsImV4cCI6MTcxNzIwMDAwMH0
Dekodiert
{
  "sub": "user_123",
  "role": "admin",
  "exp": 1717200000
}
Signature

Eine kryptographische Signatur über den kodierten Header und Payload. Die Überprüfung dieser Signatur stellt sicher, dass der Token nicht manipuliert wurde. Der geheime Schlüssel (bei HMAC) bzw. der private Schlüssel (bei RSA/ECDSA) ist niemals im Token selbst enthalten und muss serverseitig sicher aufbewahrt werden.

Kodiert
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
Dekodiert
HMACSHA256(
  base64url(header) + "." +
  base64url(payload),
  secret
)

Standard-JWT-Claims

Die JWT-Spezifikation definiert Standard-Claim-Namen für die Interoperabilität. Neben diesen registrierten Claims können Anwendungen eigene private Claims definieren — etwa Rollen, Berechtigungen oder Mandanten-IDs. Private Claims sollten durch ein Namespace-Präfix (z.B. die eigene Domain) eindeutig gemacht werden, um Konflikte mit zukünftigen Standards zu vermeiden:

ClaimNameBeschreibung
issIssuerIdentifiziert den Principal, der den Token ausgestellt hat
subSubjectIdentifiziert den Principal, der das Subjekt des Tokens ist (z.B. Benutzer-ID)
audAudienceIdentifiziert die Empfänger, für die der Token bestimmt ist
expExpirationUnix-Timestamp, nach dem der Token nicht mehr akzeptiert werden darf
nbfNot BeforeUnix-Timestamp, vor dem der Token nicht akzeptiert werden darf
iatIssued AtUnix-Timestamp, zu dem der Token ausgestellt wurde
jtiJWT IDEindeutiger Bezeichner für den Token, verhindert Token-Replay-Angriffe

Signaturalgorithmen

Der Signaturalgorithmus wird im JWT-Header deklariert. Die richtige Wahl ist für die Sicherheit entscheidend. Es ist wichtig, den erwarteten Algorithmus im Verifier explizit festzulegen und nie auf den im Token angegebenen Wert zu vertrauen, ohne ihn vorab zu prüfen:

HS256 / HS384 / HS512Symmetrisch (HMAC)

Verwendet einen gemeinsamen geheimen Schlüssel zum Signieren und Verifizieren. Einfach zu implementieren, aber der Schlüssel muss sicher an alle verifizierenden Parteien übertragen und dort geschützt gespeichert werden.

Verwenden wenn: Interne Dienste, bei denen alle Parteien kontrolliert werden.
RS256 / RS384 / RS512Asymmetrisch (RSA)

Verwendet einen privaten Schlüssel zum Signieren und einen öffentlichen Schlüssel zum Verifizieren. Der private Schlüssel verbleibt ausschließlich auf dem Auth-Server, während der öffentliche Schlüssel bedenkenlos an alle Verifier weitergegeben werden kann — beispielsweise über einen JWKS-Endpunkt.

Verwenden wenn: Microservices-Architekturen, Drittanbieter-Token-Verifizierung, OAuth2 und OpenID Connect.
ES256 / ES384 / ES512Asymmetrisch (ECDSA)

Wie RSA, aber mit kleineren Schlüsseln und schnellerer Signierung. Ein ECDSA-Schlüsselpaar mit 256 Bit bietet eine vergleichbare Sicherheit wie ein 3072-Bit-RSA-Schlüssel und ist damit besonders effizient auf Geräten mit begrenzten Ressourcen.

Verwenden wenn: Mobile und IoT-Anwendungen, bei denen Performance wichtig ist.
"alg": "none"Unsigniert — GEFÄHRLICH

Keine Signatur. Ein Token mit alg:none hat keine Integritätsgarantie und kann von jedem gefälscht werden.

Verwenden wenn: Niemals in der Produktion verwenden.

Authentifizierungsabläufe

Passwort-Grant (direkt)
  1. 1.Benutzer sendet Benutzername und Passwort an den Login-Endpunkt
  2. 2.Server validiert Anmeldedaten gegen die Benutzerdatenbank
  3. 3.Server signiert einen JWT mit Benutzer-Claims und Ablaufzeit
  4. 4.Client speichert JWT (localStorage, Cookie oder Speicher)
  5. 5.Client sendet JWT im Authorization: Bearer-Header für nachfolgende Anfragen
Autorisierungscode + PKCE (OAuth2)
  1. 1.Client leitet Benutzer zum Autorisierungsserver mit Code-Challenge weiter
  2. 2.Benutzer authentifiziert sich und autorisiert die Client-Anwendung
  3. 3.Auth-Server leitet zurück mit einem einmaligen Autorisierungscode
  4. 4.Client tauscht Code + Verifier gegen Zugriffs- und Refresh-Token aus
  5. 5.Client verwendet Zugriffstoken für API-Aufrufe; Refresh-Token zur Erneuerung

Häufige JWT-Schwachstellen

JWTs sind sicher, wenn sie korrekt implementiert werden. Dies sind die häufigsten Implementierungsfehler, die zu Sicherheitslücken führen. Viele dieser Schwachstellen entstehen nicht durch Fehler in der JWT-Spezifikation selbst, sondern durch fehlerhafte Bibliotheksimplementierungen oder mangelnde Validierung auf Anwendungsebene:

Algorithmus-Verwirrung (alg:none)Kritisch

Einige Bibliotheken akzeptieren Tokens mit alg:none. Ein Angreifer kann die Payload ändern und alg auf none setzen, um beliebige JWTs zu fälschen. Den erlaubten Algorithmus immer explizit im Verifier festlegen — nie den Wert aus dem Token-Header ungeprüft übernehmen.

HS256/RS256-VerwirrungKritisch

Wenn eine Bibliothek RS256 verifizieren soll, aber HS256 akzeptiert, kann ein Angreifer einen Token mit dem öffentlichen Schlüssel als HMAC-Geheimnis signieren. Den erwarteten Algorithmus immer explizit pinnen — niemals dynamisch aus dem Token-Header lesen.

Fehlende AblaufvalidierungHoch

Ein JWT ohne exp-Claim oder Code, der exp nicht prüft, ermöglicht die unbegrenzte Verwendung von Tokens. Abgelaufene Tokens können auch nach dem Abmelden oder Sperren eines Kontos weiterhin gültig sein, was ein erhebliches Sicherheitsrisiko darstellt.

Sensible Daten in der PayloadHoch

JWT-Payloads sind Base64-kodiert, nicht verschlüsselt. Niemals Passwörter oder andere Geheimnisse in JWT-Claims speichern. Wer einen Token abfängt — etwa durch einen Man-in-the-Middle-Angriff oder XSS — kann die gesamte Payload im Klartext lesen.

Schwache geheime Schlüssel (HS256)Mittel

HMAC-signierte JWTs mit kurzen oder vorhersehbaren Geheimnissen können offline per Brute-Force geknackt werden. Kryptographisch zufällige Geheimnisse mit mindestens 256 Bit verwenden — kurze oder sprechende Passwörter sind absolut ungeeignet.

Fehlende SignaturverifizierungMittel

JWTs ohne Signaturprüfung zu akzeptieren vertraut der Payload vollständig. Dies ist ein kritischer Fehler, der es jedem Benutzer ermöglicht, beliebige Claims zu erfinden. Die Signatur immer vor dem Vertrauen in Claims verifizieren.

Häufig gestellte Fragen

Sind JWTs verschlüsselt?

Standard-JWTs (JWS — JSON Web Signature) sind signiert, aber NICHT verschlüsselt. Die Payload ist Base64url-kodiert, was trivial umkehrbar ist. Wer einen JWT abfängt, kann seinen Inhalt sofort lesen. JWE (JSON Web Encryption) bietet echte Verschlüsselung, ist jedoch deutlich seltener verbreitet und erfordert zusätzliche Schlüsselverwaltung.

Wie lange sollte ein JWT gültig sein?

Zugriffstoken sollten kurzlebig sein: 5–60 Minuten ist typisch. Langlebige Tokens sind gefährlich, weil sie ohne eine Token-Sperrliste nicht widerrufen werden können. Refresh-Token (länger gültig, sicher gespeichert) für den Erhalt neuer Zugriffstoken verwenden. Je kürzer die Zugriffstoken-Lebensdauer, desto geringer ist das Schadenspotenzial eines gestohlenen Tokens.

Wo soll ich JWTs im Browser speichern?

HttpOnly-Cookies sind die sicherste Option — sie sind für JavaScript nicht zugänglich und verhindern XSS-Diebstahl. localStorage ist anfällig für XSS-Angriffe, vermeidet aber CSRF. Memory (JavaScript-Variable) ist am sichersten, überlebt jedoch keinen Seitenneuladen. Für die meisten Anwendungen bieten HttpOnly-Cookies mit SameSite=Strict den besten Kompromiss aus Sicherheit und Benutzerfreundlichkeit.

Kann ich einen JWT vor dem Ablauf widerrufen?

Nicht ohne serverseitigen Zustand. Die zustandslose Natur von JWTs bedeutet, dass der Server sie nicht ungültig machen kann. Lösungen: kurze Ablaufzeiten, eine Token-Sperrliste (Redis), rotierende Refresh-Token oder der Wechsel zu opaken Session-Tokens für sicherheitskritische Vorgänge. Ein hybrides Modell mit kurzen Zugriffstoken und einer Sperrliste für Refresh-Token ist in der Praxis weit verbreitet.

Was ist der Unterschied zwischen JWT und Session-Cookies?

Session-Cookies speichern eine zufällige Session-ID; der Server sucht die Session-Daten in einer Datenbank. JWTs sind eigenständig — der Server validiert die Signatur ohne Datenbankabfrage. JWTs skalieren besser auf mehrere Server, können aber ohne zusätzliche Infrastruktur nicht widerrufen werden. Session-Cookies eignen sich besser für Anwendungen, bei denen sofortiger Widerruf (z.B. nach einem Passwort-Reset) unbedingt erforderlich ist.

Welche Claims soll ich in einen JWT aufnehmen?

Das Minimum: sub (Benutzer-ID), exp (Ablauf) und iat (ausgestellt am). iss (Aussteller) für Multi-Service-Setups hinzufügen. Payloads klein halten — JWTs werden bei jeder Anfrage übertragen. Keine sensiblen Daten oder große Profilobjekte einschließen. Rollen und Berechtigungen können aufgenommen werden, sollten aber granular und auf das Notwendige beschränkt bleiben.

Ist RS256 besser als HS256?

RS256 (asymmetrisch) ist für die meisten Produktionssysteme besser, da nur der Auth-Server den privaten Schlüssel benötigt. Mehrere Dienste können Tokens mit dem öffentlichen Schlüssel verifizieren, ohne ein gemeinsames Geheimnis zu teilen. HS256 ist einfacher, erfordert aber, dass alle Verifier das gemeinsame Geheimnis kennen — bei Microservices ein erhebliches Risiko, da ein kompromittierter Dienst das Geheimnis preisgeben kann.

Was ist PKCE und warum ist es wichtig?

PKCE ist eine Erweiterung des OAuth2-Autorisierungscode-Flows, die Autorisierungscode-Abfangangriffe verhindert. Es ist für öffentliche Clients (SPAs, mobile Apps) erforderlich, die ein Client-Geheimnis nicht sicher speichern können.