A valid signature does not mean the token is for you
The question a JWT check must answer is not "was this token modified" but "was this issued by somebody I trust, for my system, for this action, and is it still valid". The signature answers only the first.
Five things to check, and the last four are the ones usually skipped:
| Check | Claim | If you skip it |
|---|---|---|
| Signature, with the algorithm you expect | header alg | You accept alg: none, or get algorithm-confused |
| Issuer | iss | Another tenant's token, or any issuer's |
| Audience | aud | A token issued for a different service works here |
| Expiry | exp, nbf | Tokens live forever |
| Authorisation for this action | scope, roles | A read token works for a write |
Two classic holes, both from trusting the token's own header:
(1) alg: none. JWT permits alg: none, meaning no signature. A library verifying "with whatever alg the header says" sees none, concludes nothing needs checking, and returns success. Fix: always state the algorithm you expect; never let the token declare it.
(2) Algorithm confusion. If the server accepts both RS256 and HS256, an attacker takes your public key — which is public — and signs a token with HS256 using that public key as the secret. The server sees alg: HS256, uses the RSA key as an HMAC secret, and the signature matches.
One point worth stating because it is counter-intuitive: the kid header is not trustworthy either. It names which key in your JWKS to use, and a kid pointing at a file path or an attacker-controlled URL has been a real vulnerability class. kid is for looking up within a key set you already have, not for loading a new key.
And one thing about JWTs generally: there is no revocation. An issued token is valid until exp, regardless of a password change, a deleted account, or a removed permission. That is not a bug to fix but a property to design around — which session-lifetime does.
Comments
Commenting needs an account with at least one completed lesson. That condition is what keeps this thread worth reading: every point belongs to someone who can be asked back, and reputation accrues over time.
You can still read every comment below without an account. Signing in brings you back to this exact spot, not to the top of the page.
Loading comments…