Common JWT Security Pitfalls

While JWTs are powerful, misconfigurations can lead to severe breaches. Understanding common vulnerabilities is essential for secure implementation.

1. The alg:none Attack

Some libraries accept "alg": "none" by default. An attacker can remove the signature and set alg: none to bypass verification.

Fix: Explicitly disable none algorithm in your JWT library.

2. Weak or Exposed Secrets

Using short, guessable, or hardcoded secrets for HS256 makes brute-force attacks trivial.

  • Use cryptographically strong secrets (≥256 bits)
  • Rotate keys regularly
  • Never commit secrets to version control

3. Accepting Tokens Without Verification

Decoding a JWT doesn’t mean it’s valid. Always verify the signature before trusting claims.

4. Overloading the Payload

Large JWTs increase header size and can be used in DoS attacks. Keep payloads minimal.

5. Missing Audience & Issuer Checks

Without validating aud and iss, an attacker could reuse a token across applications.

6. Improper Error Handling

Leaking validation errors can help attackers craft valid tokens. Return generic error messages.

7. Storing JWTs in localStorage

XSS attacks can steal tokens from browser storage. Prefer HttpOnly, Secure cookies when possible.

Best Practices Summary

  • Always verify signature
  • Enforce strong algorithms (RS256 preferred over HS256)
  • Set and check exp, iat, nbf
  • Use allowlists for aud and iss
  • Implement token revocation when needed

FAQ

Should I use HS256 or RS256?

RS256 (asymmetric) is preferred in microservices. HS256 is acceptable if the secret is strongly protected.

Can I blacklist JWTs?

Yes, but use short expiration to reduce need. Store JTI in Redis with TTL.

What about refresh tokens?

Store refresh tokens securely server-side; issue short-lived access tokens.

Security is in the implementation. A JWT is only as strong as your validation logic.