JWT secret brute force
Recover a weak HMAC signing secret from a JWT by testing a wordlist against the token’s own signature, in the browser.
Open in ctfpalAn HS256 token carries everything needed to test a candidate secret offline: the signed input is the header and payload you already hold, and the expected output is the signature. That makes secret recovery a pure local computation - no requests to the target, no rate limits, no detection.
Why it works so often
HMAC secrets are supposed to be long random keys. In practice they are secret, changeme, the framework’s documentation example, or the application’s name. A few thousand candidates covers a startling share of real deployments and nearly all CTF challenges.
signing_input = f"{header_b64}.{payload_b64}".encode()
for candidate in wordlist:
mac = hmac.new(candidate.encode(), signing_input, hashlib.sha256).digest()
if base64url(mac) == signature_b64:
return candidateOnce you have the secret you are no longer forging - you are legitimately signing. Change any claim you like and re-sign; the token verifies because it genuinely is valid. That is a stronger position than an alg=none bypass, which only works against a broken verifier.
Common questions
- Does brute forcing the secret alert the server?
- No. Every candidate is tested against the signature you already have, entirely offline. The server sees nothing until you use the forged token.
Part of a module
6. Web attacks and session tokens
Read and forge JWTs and Flask sessions, find content nobody linked to, and probe for injection with detection payloads.
Practise on real challenges
Go deeper
- Attacking JWTs: alg=none, algorithm confusion, and the header fields nobody auditsA JSON Web Token is a signed claim you were handed and asked to give back. Every classic JWT bug is a place where the verifier lets the token choose how it is verified - alg=none, RS256 to HS256 confusion, kid injection, and attacker-hosted key URLs.
Related tools
JWT decoder and signature verifier
Decode a JSON Web Token’s header and payload and verify HS256/HS384/HS512 signatures against a known secret - all locally.
JWT alg=none bypass generator
Forge an unsigned JWT by setting the algorithm to none, and understand why some libraries still accept it.
In-browser hash cracker with rule transforms
Crack MD5, SHA-1, SHA-256, SHA-384, and SHA-512 against a wordlist in your browser, with leetspeak, case, reversal, and digit-append rules.