JWT Forgery (Leaked Secret)
Full command arsenal in the cheatsheetA JSON Web Token (JWT) signed with HMAC (HS256) protects its integrity with a single shared secret key between issuer and verifier. If that key leaks, the guarantee disappears entirely: the attacker can fabricate arbitrary tokens (change the user, set is_admin:true, add claims) and sign them with the stolen key, and the server will accept them as legitimate. It is the difference between a JWT as proof of identity and a JWT as plain text signed with a secret that is no longer secret.
Where the key comes from. Almost always from carelessness: the key in the repository or in a config file (config.py, settings.py, .env) that the attacker reads via an LFI, a source-code leak or a secret in git history. Short or default keys also fall to brute force (hashcat -m 16500).
How it is forged. The reference tool is jwt_tool:
python3 jwt_tool.py '<original_jwt>' -T -S hs256 -p '<leaked_key>'Tamper mode (-T) lets you edit the payload (for example, add "debug": true or raise a role) and -S hs256 -p re-signs it with the correct key. The resulting token passes any signature check on the server.
Relation to alg:none. It is a different attack from the same family: with alg:none the signature is voided because the server does not validate it; here the signature is validated, but the attacker knows the key and signs it themselves. The defence is shared: validate the expected algorithm and, above all, protect the key.
How to detect it. A token forged with the correct key passes signature verification, so it raises no errors: detection lives in the content and the consistency. Server-side, a useful rule compares the token's claims against real state: a role/is_admin that doesn't match the permissions the database holds for that user, or an admin token for an account that never was one, is the signal. The same sub reused from disparate IPs, or an iat/exp outside the windows the server issues, also point to forgery. The root cause is proactively detectable: grepping for the HMAC key in code and git history (see credentials in source code) finds it before the attacker does.
Defence. Do not embed the key in code or readable files; use environment variables or a secret manager; rotate the key on suspected leak; prefer asymmetric algorithms (RS256), where the verifier only needs the public key, so leaking it does not allow forging. Related to JWT and credentials in source code.
Machines where it's used
- BackendHackTheBox