JWT Vulnerabilities Explained

Share

TL;DR

JWTs are commonly used for authentication but easy to implement wrong. The main vulnerabilities are: accepting the "none" algorithm, using weak secrets that can be brute-forced, and algorithm confusion attacks. Always specify the allowed algorithm explicitly and use a strong secret (256+ bits for HS256).

Common JWT Vulnerabilities

1. Algorithm Confusion

Some libraries accept the algorithm from the token header instead of enforcing one. Attackers can switch from RS256 to HS256 and sign with the public key.

Vulnerable: accepting algorithm from token
// VULNERABLE: doesn't specify algorithm
jwt.verify(token, publicKey);

// Attacker changes header to HS256 and signs with public key
// { "alg": "HS256" } + HMAC(payload, publicKey)

2. None Algorithm

Old or misconfigured libraries accept alg: "none" which skips signature verification entirely.

Token with no signature
// Attacker sends:
// Header: { "alg": "none" }
// Payload: { "sub": "admin", "role": "admin" }
// Signature: (empty)

// Bad library accepts it as valid!

3. Weak Secrets

Short or common secrets can be brute-forced. Tools like hashcat can crack weak JWT secrets quickly.

Weak secrets: "secret", "password123", or any string under 32 characters can be cracked. Use at least 256 bits of randomness for HS256.

Secure JWT Implementation

Safe JWT verification
import jwt from 'jsonwebtoken';

// Always specify the algorithm explicitly
const decoded = jwt.verify(token, process.env.JWT_SECRET, {
  algorithms: ['HS256'],  // Reject any other algorithm
  issuer: 'yourapp.com',
  audience: 'yourapp.com'
});

// Generate a strong secret (run once, save to env)
// node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"

Should I use HS256 or RS256?

HS256 (symmetric) is simpler for single services. RS256 (asymmetric) is better when multiple services verify tokens, as you can share the public key without exposing the private key.

How do I handle JWT expiration?

Use short-lived access tokens (15 min to 1 hour) with refresh tokens. Always check the exp claim and reject expired tokens.

Should I store JWTs in localStorage?

LocalStorage is vulnerable to XSS. Consider HttpOnly cookies for web apps. For SPAs, weigh the tradeoffs carefully based on your XSS risk.

Check Your JWT Implementation

Our scanner tests for common JWT vulnerabilities.

Start Free Scan
Vulnerability Guides

JWT Vulnerabilities Explained