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
audandiss - 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.