JSON Web Tokens

Check List

Methodology

None Algorithm

1

Log in to the target site, complete the authentication process, and inspect the requests using Burp Suite

2

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

3

header like

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

and payload

{
  "user": "guest",
  "role": "user"
}
4

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

5

Now inject the word admin in the payload request as follows

{
  "user": "admin",
  "role": "admin",
  "iat": 1731670400,
  "exp": 9999999999
}
6

Now convert the request to base64 and replace the previous Jwt token

Base64URL encode header like → eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0

7

Base64URL encode payload like → eyJ1c2VyIjoiYWRtaW4iLCJyb2xlIjoiYWRtaW4iLCJpYXQiOjE3MzE2NzA0MDAsImV4cCI6OTk5OTk5OTk5OX0

Append . + empty string → final token

eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.eyJ1c2VyIjoiYWRtaW4iLCJyb2xlIjoiYWRtaW4iLCJpYXQiOjE3MzE2NzA0MDAsImV4cCI6OTk5OTk5OTk5OX0.
8

Then, after replacing the tampered jwt token with the previous jwt that the server had set, we send the request

9

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

1

Access the target application and locate login or authenticated endpoints

2

Inspect network traffi Burp Suite to identify JWT tokens in headers (Authorization: Bearer ...) or localStorage

3

Copy a valid JWT token and decode it using a tool like jwt.io

4

Examine the header to confirm the presence of the kid (Key ID) field,

{
  "alg": "HS256",
  "typ": "JWT",
  "kid": "1"
}
5

Modify the kid value to point to a publicly accessible file

{
  "alg": "HS256",
  "typ": "JWT",
  "kid": "../../public/css/style.css"
}
6

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)

7

Send the forged token to the application via an authenticated request

8

Check if the application accepts the token and grants access

9

If successful, the server is using the specified file (main.css) as the verification key, bypassing intended security


SQL Injection Via KID

1

Modify the kid value to inject SQL

{
  "alg": "HS256",
  "typ": "JWT",
  "kid": "1' UNION SELECT 'mysecret'--"
}
2

Re-encode the token with the manipulated header and sign it using the injected string (key or secret) as the HMAC secret

3

Submit the token to the application

4

Verify if the application validates the token using the injected string as the secret key

5

If access is granted, the kid parameter is vulnerable to SQL injection, allowing arbitrary key manipulation


JWT Forging via Default Secret Exploitation

1

Sign up and log in to the target application while proxying traffic through Burp Suite

2

Capture the /api/auth/login (equivalent) POST request and its response containing the JWT token

3

Decode the JWT using jwt.io or token.dev

4

Observe the payload contains sub, role, role_id, exp

5

Check Burp Suite’s Issues tab for a warning JWT signed with default secret: CHANGE_ME

6

Confirm the application uses HMAC with the hardcoded secret CHANGE_ME

7

Create a forged payload targeting admin access like

{
  "sub": "1",
  "role": "admin",
  "role_id": 1,
  "exp": 9999999999
}
8

Sign the token using HS256 and the secret CHANGE_ME

9

In Burp Suite, configure Match and Replace rule

10

Forward all subsequent requests with the forged token

11

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

1

Register Test Account A and Test Account B on the target platform

2

Log in to each account separately to obtain

  • Access Token A + Refresh Token A

  • Access Token B + Refresh Token B

3

From Test Account A, trigger a token refresh

4

Capture the new access token returned

5

Use Test Account B’s refresh token with Test Account A’s access token

6

Send the request

7

If response contains a new valid access token with Test Account A’s identity → Association bypass confirmed


Replay Attack

1

Log in to the target application

2

Capture a valid JWT from Authorization: Bearer header or response body

3

Browse the app and trigger actions like Profile update

4

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

5

If each replay executes the action again (profile updated 5 times, 5 emails sent) ,Replay attack confirmed


White Box

Cheat Sheet

Last updated