security authentication ai_generated true

JWT validation bypassed by changing algorithm to 'none' in token header

ID: security/jwt-alg-none-bypass

Also available as: JSON · Markdown
92%Fix Rate
95%Confidence
3Evidence
2023-01-01First Seen

Version Compatibility

VersionStatusIntroducedDeprecatedNotes
any active

Root Cause

RFC 7519 defines 'none' as a valid JWT algorithm (unsecured JWS). If the server doesn't explicitly enforce the expected algorithm, an attacker can forge tokens by setting alg:none and removing the signature. Many JWT libraries accepted this by default.

generic

Workarounds

  1. 98% success Always specify allowed algorithms explicitly in jwt.decode()
    jwt.decode(token, key, algorithms=['HS256'])  # NEVER omit algorithms parameter
  2. 92% success Use asymmetric algorithms (RS256/ES256) and separate signing/verification keys
    RS256 with private key for signing, public key for verification. Even if alg is changed to HS256, the public key won't produce valid HMAC.
  3. 90% success Reject tokens with alg:none at the middleware level
    header = jwt.get_unverified_header(token); if header['alg'] == 'none': raise SecurityError()

Dead Ends

Common approaches that don't work:

  1. Validate JWT without specifying expected algorithms 95% fail

    Without an explicit algorithm whitelist, libraries may accept alg:none tokens. The signature verification is skipped entirely for unsigned tokens.

  2. Check the alg field from the JWT header to decide verification method 92% fail

    Attacker controls the JWT header. Using attacker-supplied alg means they choose the verification algorithm. Classic confused-deputy attack.