root@nikhil:~$ _
Interactive · Runs a real analyzer · Nothing is stored

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.

or try one:

How a JWT actually works

1

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.

2

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.

3

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.