JWT alg=none
auth · medium · +40 XP
// what is JWT alg=none?
JWT alg=none = the JSON Web Token spec allows an unsigned token with alg: none. If your verifier is lazy and calls jwt.decode(token, key=None) without explicitly rejecting none, an attacker mints a token with {role:'admin'} and no signature — and you accept it. The other classic is alg: HS256 confusion (use the RSA public key as the HMAC secret to sign as if you held the private key).
// how attackers detect it
- [01]Base64-decode header (
token.split('.')[0]). Whatalgdoes it accept? - [02]Forge a token with
alg: none+ your desired claims + empty signature. Send it. Does it work? - [03]Try
alg: HS256while signing with the server's public RSA key (well-known JWKS endpoint).
// how defenders prevent it
- ✓Pin the algorithm at decode time —
jwt.decode(token, key, algorithms=['RS256']), never auto-detect. - ✓Reject
alg: noneexplicitly. Most libs do this now; older versions don't. - ✓Short token lifetimes + key rotation. Don't trust the
kidheader blindly — validate against an allow-list.
// real-world incidents
CVE-2022-23529
node-jsonwebtoken algorithm confusion
Library-level — affected thousands of Node apps until patched.
CVE-2023-48795
Terrapin SSH (related: signature confusion)
Algorithm-downgrade pattern — same family of bugs.
// hands-on tips for this lab
- ›Forge header:
eyJhbGciOiJub25lIn0, body:eyJyb2xlIjoiYWRtaW4ifQ, sig: empty. SendAuthorization: Bearer <header>.<body>.
was this lesson helpful?
3 of 10 · web