JWT Inspector
Paste a JSON Web Token to decode its claims and surface where it is weak - then watch a guessable signing secret get recovered by dictionary attack, and forge a token of your own to see exactly what that lets an attacker do.
Your token is analyzed server-side and never logged or stored. Don't paste a production token you rely on - the point of this tool is that weak ones are trivial to break.
Header
Payload
Signature
Claims
| Claim | Value | Meaning |
|---|
Findings
Forge a token
The secret is known, so you now control the token completely. Edit any claim below and re-sign - the forged token will verify as genuine. This is the exact move an attacker makes after cracking the secret.
How a JWT actually works
Header . Payload . Signature
Three base64url segments joined by dots. The first two are just JSON - anyone can read and change them. They are not encrypted, only encoded.
The signature is the only defence
The signature is computed over header.payload with a secret. If a
verifier trusts the claims, it is trusting that signature - nothing else.
Weak signature ⇒ no security
If the algorithm is none, or the HMAC secret is guessable, the
signature stops meaning anything and every claim becomes attacker-controlled.
Build notes
From scratch, on the standard library
The whole JOSE stack - base64url codec, HMAC signing, constant-time
verification, the cracker, the forger - is implemented on Python's standard
library. No PyJWT, no cryptography. For a tool whose
job is to reason about signatures, being able to read every line that touches
one is the point.
The cracker is bounded and constant-time
HS256 is HMAC - checkable offline at millions of guesses per second. Verification
uses hmac.compare_digest (the same constant-time comparison the
tool flags others for missing), and the guess count is capped so an oversized
wordlist can never turn a request into a denial of service.
The score is derived, not asserted
The risk number comes from the findings themselves - the worst finding sets the floor, additional distinct problems nudge it up. It can never disagree with the list beneath it, and a healthy, strong, short-lived token scores under 4.0.
A bug the tests caught
The claim-edit parser accepted a JSON array like [1,2,3] and
silently returned an empty edit set, because the array fell through to the
key=value line parser. Now anything that opens like JSON but is not
an object is rejected. 61 tests, every check paired with a
healthy-token case that must stay quiet.