JWT vulnerabilities
A JWT (JSON Web Token) is like an access pass that the server gives you after you log in. It’s a long string with three parts, separated by dots:
HEADER.PAYLOAD.SIGNATURE
eyJhbGciOi... (header).eyJzdWIiOi... (payload).SGVsbG8sIHdv... (signature)What does each part contain?
Header
Describes the algorithm used to sign the token (e.g., HS256, RS256).
It's a Base64-encoded JSON.
Payload
Contains “claims” – data like your name, role, email, isAdmin status, etc.
Also a Base64-encoded JSON.
Anyone can read this part if they have the token!
Signature
This ensures the token hasn’t been tampered with.
Created using a secret key known only to the server.
If you change the header or payload, the signature becomes invalid.
Risky Header Parameters
alg: Can be changed tononeto bypass signature validation.jwk: May allow the attacker to provide a public key and sign a token with their private key.kid: If not validated securely, can be exploited via path traversal or external key injection.
Useful resouse:
Burpsuite Recommended extension:
JWT Editor
Methodology
Signature Validation Bypass
Modify the payload (e.g., change user ID, role, etc.) to impersonate another user.
Observe if the server still accepts the token, indicating improper signature verification.
Algorithm none Bypass
Change the
algparameter in the header tonone.Remove the signature part but keep the final dot (e.g.,
header.payload.).If accepted, the server is not validating the signature.
Brute Force the Signature Key
Developers may forget to change default secrets.
Use Hashcat to brute-force the key:
hashcat -a 0 -m 16500 'HEADER.PAYLOAD.SIGNATURE' jwt.secrets.listHeader Injection Techniques
🔓 jwk Header Injection
jwk Header InjectionGenerate an RSA key in Burp Suite.
Modify the payload as needed.
In Burp Repeater, use
Attack → Embedded JWK.Send the token with your public key embedded in the header.
🌐 jku Header Injection
jku Header InjectionHost a JWK Set file like:
{
"keys": [ YOUR_JWK ]
}In the JWT header:
Set
kidto your key ID.Add a
jkuparameter pointing to your hosted JWK Set.
Sign the token with your private key and send it.
🗂️ kid Path Traversal
kid Path TraversalCreate a symmetric key in Burp.
Replace the
kvalue with a Base64-encoded null byte (AA==).In the header, set:
"kid": "../../../../../../../dev/null"Modify the payload as needed, sign and send.
Algorithm Confusion Attack (RS256 → HS256)
Retrieve the server's public key (commonly found at
/jwks.jsonor/.well-known/jwks.json).Generate a new RSA Key in Burp → Export as PEM.
Convert PEM to Base64.
Create a Symmetric Key and replace the
kvalue with the Base64 version.In the header:
"alg": "HS256"Modify the payload as needed, sign and send.
Algorithm Confusion Without Exposed Key
Obtain two JWTs (either same user at different sessions, or different users).
Use
sig2nto derive the HMAC key:
sudo docker run --rm -it portswigger/sig2n TOKEN1 TOKEN2Copy the derived key.
Create a new Symmetric Key in Burp and set
kto that key.Set
algin the header toHS256.Modify the payload, sign, and send.
Last updated