Security
Security/senior/freq 4/5

JWT — Beyond the Hello World

JWTs are great for stateless authz but terrible for session management. Keep them short-lived, validate everything, and never roll your own.

jwtauthsecurity

Deep dive

Validate, always

  • Signature against the issuer's JWKS.
  • iss matches the expected issuer.
  • aud matches your API.
  • exp and nbf against current time with small clock skew tolerance.
  • Algorithm: pin to expected (RS256, ES256). Never allow alg=none or unbounded selection — that was a real CVE class.

Revocation

JWTs can't be revoked before expiry without a server-side denylist — which defeats statelessness. Mitigations: short lifetimes (5–15 min), refresh-token rotation, and a denylist of compromised jti values pulled at the gateway.

Don't put sensitive data in JWTs

They are base64, not encrypted. Use JWE if you must encrypt, or just keep secrets out.

Real-world example

From production

An incident response: stolen refresh token gave attacker 30 days of access. Fix: refresh token rotation (one-time use, family invalidation on reuse) plus reduce access token to 10 min. Detection of stolen refresh became automatic — reuse triggers family revoke.

Interview questions

1 senior-level
Q1How do you revoke a JWT?

You usually don't, before expiry. Mitigate with short access-token lifetimes, refresh-token rotation with reuse detection, and a denylist of jti for incidents. If you need real revocation, opaque tokens with central introspection are a better fit.

Common mistakes

  • Accepting any alg from the token header.

  • Long-lived access tokens 'for convenience'.

  • Putting PII in JWT claims.

Trade-offs

  • Stateless JWT scales but limits revocation; opaque tokens add a hop but give control.

Related