JWT Attacks & Bypass
Crack weak signing secrets, exploit signature verification flaws, and abuse algorithm confusion in JSON Web Tokens.
// prerequisite reading
Anatomy of a JWT
A JSON Web Token consists of three base64url-encoded parts separated by dots (.):
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkFsaWNlIiwicm9sZSI6InVzZXIifQ.Signature...
[ HEADER ].[ PAYLOAD ].[ SIGNATURE ]
- Header: Algorithm & token type (e.g.,
{"alg": "HS256", "typ": "JWT"}). - Payload: Claims and user metadata (e.g.,
{"user": "admin", "role": "admin"}). - Signature: Verification hash created using secret key / private key over
Header.Payload.
1. Unverified Signature / none Algorithm
Some flawed JWT libraries accept tokens signed with the none algorithm, bypassing signature checks entirely:
- Decode the token header and payload.
- Modify payload claims (e.g.,
"role": "admin"or"user": "admin"). - Change header algorithm to
"alg": "none"(or"None","NONE","nOnE"). - Remove the signature segment completely while retaining the trailing dot:
eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.eyJ1c2VyIjoiYWRtaW4iLCJyb2xlIjoiYWRtaW4ifQ.
2. Brute-Forcing Weak Secrets (HS256)
Symmetric JWT signing (HS256) relies on a shared secret key. If the secret is weak, it can be cracked offline using dictionary attacks.
Using hashcat
hashcat -m 16500 jwt_token.txt /usr/share/wordlists/rockyou.txt
Using jwt_tool
python3 jwt_tool.py <JWT_STRING> -d /usr/share/wordlists/rockyou.txt
Once the secret is recovered (e.g., secret123), re-sign forged payloads using PyJWT or jwt_tool:
import jwt
forged_token = jwt.encode({"user": "admin", "role": "admin"}, "secret123", algorithm="HS256")
print(forged_token)
3. Algorithm Confusion Attack (RS256 to HS256)
RS256 uses asymmetric keys (Private key to sign, Public key to verify). HS256 uses a symmetric secret key.
If an application verifies signatures using RS256 but accepts HS256 tokens:
- Obtain the target server’s public key (e.g., from
/jwks.json,/.well-known/jwks.json, or exported TLS cert). - Change the header algorithm from
RS256toHS256. - Sign the forged token using the public key string as the symmetric HMAC secret key!
4. Key ID (kid) Header Injection
The kid header parameter specifies which key file or database entry to use for verification.
- Path Traversal in
kid: Setkidto../../../../dev/nullor a known file on disk (like/etc/issue), then sign the token with an empty string or the contents of that file as the HMAC key:{ "alg": "HS256", "typ": "JWT", "kid": "../../../../../dev/null" } - SQL Injection in
kid: Inject SQL statements intokidparameter to return controlled keys:
Then sign payload with{ "alg": "HS256", "kid": "' UNION SELECT 'my_known_secret' -- -" }my_known_secret.