JSON Web Tokens
Check List
Methodology
None Algorithm
Log in to the target site, complete the authentication process, and inspect the requests using Burp Suite
If the requests used jwt, decode it using the Burp suite extension called JWT Editor or copy it and decode it on the following site
Paste token into https://jwt.io
header like
{
"alg": "HS256",
"typ": "JWT"
}and payload
{
"user": "guest",
"role": "user"
}Create this exact JWT (no signature needed)
{
"alg": "none",
typ": "JWT"
}We can write none payloads in uppercase and lowercase, like this
none
None
NONE
nOnE
Now inject the word admin in the payload request as follows
{
"user": "admin",
"role": "admin",
"iat": 1731670400,
"exp": 9999999999
}Now convert the request to base64 and replace the previous Jwt token
Base64URL encode header like → eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0
Base64URL encode payload like → eyJ1c2VyIjoiYWRtaW4iLCJyb2xlIjoiYWRtaW4iLCJpYXQiOjE3MzE2NzA0MDAsImV4cCI6OTk5OTk5OTk5OX0
Append . + empty string → final token
eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.eyJ1c2VyIjoiYWRtaW4iLCJyb2xlIjoiYWRtaW4iLCJpYXQiOjE3MzE2NzA0MDAsImV4cCI6OTk5OTk5OTk5OX0.Then, after replacing the tampered jwt token with the previous jwt that the server had set, we send the request
Then we check in localstorage whether the tampered jwt is stored or not and if it is stored we check whether we have access to an admin feature or admin pages and if we have access the vulnerability is confirmed
KID Manipulation Vulnerability
Access the target application and locate login or authenticated endpoints
Inspect network traffi Burp Suite to identify JWT tokens in headers (Authorization: Bearer ...) or localStorage
Copy a valid JWT token and decode it using a tool like jwt.io
Examine the header to confirm the presence of the kid (Key ID) field,
{
"alg": "HS256",
"typ": "JWT",
"kid": "1"
}Modify the kid value to point to a publicly accessible file
{
"alg": "HS256",
"typ": "JWT",
"kid": "../../public/css/style.css"
}Re-encode the token with the manipulated header and an empty or arbitrary payload, ensuring the signature matches the file content (if server uses file as key)
Send the forged token to the application via an authenticated request
Check if the application accepts the token and grants access
If successful, the server is using the specified file (main.css) as the verification key, bypassing intended security
SQL Injection Via KID
Modify the kid value to inject SQL
{
"alg": "HS256",
"typ": "JWT",
"kid": "1' UNION SELECT 'mysecret'--"
}Re-encode the token with the manipulated header and sign it using the injected string (key or secret) as the HMAC secret
Submit the token to the application
Verify if the application validates the token using the injected string as the secret key
If access is granted, the kid parameter is vulnerable to SQL injection, allowing arbitrary key manipulation
JWT Forging via Default Secret Exploitation
Sign up and log in to the target application while proxying traffic through Burp Suite
Capture the /api/auth/login (equivalent) POST request and its response containing the JWT token
Observe the payload contains sub, role, role_id, exp
Check Burp Suite’s Issues tab for a warning JWT signed with default secret: CHANGE_ME
Confirm the application uses HMAC with the hardcoded secret CHANGE_ME
Create a forged payload targeting admin access like
{
"sub": "1",
"role": "admin",
"role_id": 1,
"exp": 9999999999
}Sign the token using HS256 and the secret CHANGE_ME
In Burp Suite, configure Match and Replace rule
Forward all subsequent requests with the forged token
If you see the following values in the server response, it means you have access to the admin dashboard or sensitive data
JWT Refresh Token Association Bypass
Register Test Account A and Test Account B on the target platform
Log in to each account separately to obtain
Access Token A + Refresh Token A
Access Token B + Refresh Token B
From Test Account A, trigger a token refresh
Capture the new access token returned
Use Test Account B’s refresh token with Test Account A’s access token
Send the request
If response contains a new valid access token with Test Account A’s identity → Association bypass confirmed
Replay Attack
Log in to the target application
Capture a valid JWT from Authorization: Bearer header or response body
Browse the app and trigger actions like Profile update
In Burp Repeater Copy a state-changing request (POST /api/user/update), Do not modify any parameter or timestamp, Send multiple times with the same JWT
If each replay executes the action again (profile updated 5 times, 5 emails sent)
,Replay attack confirmed
White Box
Cheat Sheet
Last updated