skip to main content
hacking.communityplay in the sandbox.

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]). What alg does it accept?
  • [02]Forge a token with alg: none + your desired claims + empty signature. Send it. Does it work?
  • [03]Try alg: HS256 while 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: none explicitly. Most libs do this now; older versions don't.
  • ✓Short token lifetimes + key rotation. Don't trust the kid header 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. Send Authorization: Bearer <header>.<body>.
was this lesson helpful?

// go deeper

// install app

Install hacking.community for fast access, offline reading, and push notifications. No app store needed.