JWT-Claims und Autorisierungsgrenzen
Wie man entscheidet, welchen Claims man vertraut, welche erneut geprüft werden müssen und wo JWT-Autorität enden sollte.
JWT-Claims sind bequem, weil sie Fakten nah an die Request bringen. Diese Bequemlichkeit wird gefährlich, wenn Claims Autorisierung ersetzen. Ein signiertes Token kann beweisen, dass ein Issuer zu einem Zeitpunkt eine Aussage gemacht hat. Es beweist nicht, dass diese Aussage noch stimmt, dass die Ressource zum selben Tenant gehört oder dass ein Benutzer genau jetzt eine bestimmte Aktion ausführen darf.
Identität ist keine Autorisierung
sub identifiziert einen Principal. scope oder roles beschreiben grobe Berechtigungsgruppen. tenant_id kann den beim Login gewählten Tenant beschreiben. Keiner dieser Claims beantwortet automatisch: "Darf dieser Benutzer diese Rechnung freigeben?" Die Ressource braucht weiterhin Eigentumsprüfungen, Tenant-Grenzen und manchmal Zustandsprüfungen. Angreifer suchen Stellen, an denen ein Claim wie ein Datenbank-Join behandelt wird, der nie stattfindet.
Ein häufiger Bug steckt in Multi-Tenant-APIs: Der Handler vertraut tenant_id aus dem Token und filtert damit Datensätze, während die Route zusätzlich einen Tenant oder Account im Pfad akzeptiert. Wenn diese Werte nicht übereinstimmen, muss das System ablehnen. Stilles Bevorzugen eines Werts erzeugt verwirrendes Verhalten. Vertrauen in den Pfad erzeugt einen Autorisierungs-Bypass.
Claims altern schlecht
Rollen, Planstufen, Organisationsmitgliedschaften und Feature-Berechtigungen können sich ändern, während ein Token gültig bleibt. Leben Access Tokens eine Stunde, kann das Entfernen einer Admin-Rolle eine Stunde wirkungslos bleiben, sofern die API nicht den aktuellen Zustand prüft. Für risikoarme Lesezugriffe mag das passen. Für Billing, Exporte, Admin-Aktionen und destruktive Operationen sind veraltete Claims meist nicht akzeptabel.
Eine praktische Grenze
Nutze JWTs für Authentifizierungsfakten und grobe Routing-Entscheidungen: Issuer, Subject, Audience, Expiration, Session-ID und vielleicht einen kompakten Scope. Nutze serverseitige Checks für Ressourcenautorisierung. Wenn Performance zählt, cache Autorisierungsentscheidungen mit kurzer TTL und expliziter Invalidierung, statt jede Berechtigung ins Token zu stopfen.
Claim-Missbrauch testen
In einem Pentest änderst du jeweils einen Claim und beobachtest Objektzugriffe. Ändere tenant_id, org_id, scope, role, email_verified und Feature-Flags. Halte die Signatur gültig, wenn du einen Test-Issuer kontrollierst, oder nutze Low-Privilege-Tokens über mehrere Endpunkte, um Stellen zu finden, die Claims vor Verifikation dekodieren. GraphQL braucht besondere Aufmerksamkeit, weil Resolver Autorisierung oft uneinheitlich anwenden.
Designregel
Ein JWT sollte genug Information tragen, um den Aufrufer zu identifizieren und den richtigen Verifier zu wählen, nicht genug, um das Autorisierungsmodell zu umgehen. Wenn ein Claim Geld, Datengrenzen oder Admin-Macht beeinflusst, sollte die API erklären können, warum sie diesem Claim genau in diesem Moment vertraut hat.