← Blog
October 23, 2026 · 7 min

The JWT Security Checklist (2026)

Every check that matters before you ship JWT authentication: key strength, algorithm pinning, token lifetime, storage, revocation, and rotation.

Before you sign anything

Most JWT vulnerabilities trace back to five decisions: the key, the algorithm, the lifetime, the storage, and the revocation story. Run through this checklist before your auth code ships.

1. Key strength

  • Generate the secret from a CSPRNG — crypto.randomBytes(64) in Node, secrets.token_urlsafe(64) in Python, openssl rand -base64 64 on the command line. Never a passphrase, company name, or doc example.
  • Match key size to algorithm: HS256 ≥ 32 bytes, HS384 ≥ 48 bytes, HS512 ≥ 64 bytes. A 16-character "secret" is brute-forceable in seconds.
  • Never commit the secret to git. Store it in an environment variable or a secrets manager, and use different secrets for dev, staging, and production.
  • Test your current key with a strength validator — if it fails entropy or length checks, rotate it.

2. Algorithm pinning

  • Pin the expected algorithm server-side. Never read alg from the token header and follow it — that is the algorithm-confusion attack (alg: none, RS256→HS256 key confusion).
  • With libraries like jsonwebtoken, pass algorithms: ["HS256"] explicitly on every verify() call.
  • Reject tokens whose header algorithm doesn't match before computing anything.

3. Token lifetime

  • Keep access tokens short: 5–15 minutes. A stolen long-lived JWT is valid until it expires — there is no server-side kill switch by default.
  • Pair short access tokens with refresh tokens, and rotate the refresh token on every use.
  • Always check exp and nbf server-side. Compare in seconds, not milliseconds — Date.now() returns milliseconds and this mismatch silently breaks expiry checks.

4. Payload hygiene

  • The payload is encoded, not encrypted — anyone holding the token can read it. Never put passwords, API keys, or sensitive PII in claims.
  • Keep claims minimal: a user or session ID and the timestamps you need. Look up sensitive data server-side.

5. Storage

  • Browser: prefer httpOnly, Secure, SameSite cookies over localStorage — httpOnly keeps the token away from JavaScript and out of reach of XSS.
  • If you must use localStorage (e.g. native-like SPAs without a backend cookie story), accept the XSS trade-off explicitly and invest in a strict CSP.
  • Never store refresh tokens in localStorage.

6. Revocation and rotation

  • Decide how a token dies before the token exists: a short expiry, a deny-list, or a version claim checked server-side.
  • Plan key rotation from day one with a kid header so two secrets can validate during the rollover window.
  • Rotate immediately after any suspected leak, then invalidate issued tokens.

7. Verification hygiene

  • Verify the signature on every request that trusts the token — decoding without verifying proves nothing.
  • Reject tokens from cookies with the wrong SameSite/origin context to limit CSRF exposure.
  • Log verification failures with their reason, but never log the full token or the secret.

Work through the list top to bottom — the first three items stop the most attacks. Generate a properly-sized key with the JWT secret generator, validate it, and you've already covered the items that cause the worst real-world incidents.