Skip to content
hashkey.bond

Archivesecurity

JWT Pitfalls That Keep Coming Back

Algorithm confusion, unchecked claims, and treating a signed token as authorization.

Published
Reading time
1 min read

A JWT is a signed JSON payload. It is not encrypted, it is not revocable by default, and it is not an authorization system.

Recurring bugs

  • alg: none: libraries that accept unsigned tokens. Always pin the expected algorithm; never trust the header to choose it.
  • HS256/RS256 confusion: verifying an RSA token with the public key as an HMAC secret. Pin both algorithm and key type.
  • Ignoring aud and iss: a token minted for another service is accepted by yours.
  • Trusting exp alone: clock skew and long lifetimes; also check nbf and iat where relevant.
  • Storing secrets in claims: the payload is base64, not encrypted.
  • No revocation: a stolen token is valid until expiry. Use short lifetimes plus refresh tokens with server-side state.

A safer default

Short-lived access tokens (minutes), audience-bound, algorithm-pinned, validated with a maintained library, and backed by a revocation list for high-risk actions.

Takeaway: JWT is a serialization format with a signature. Authorization decisions still belong on the server, checked against current state.