JWT decoder and security checker
Paste a token and read what it actually contains, along with what its header, claims and lifetime give away. Nothing is uploaded: the decoding and the checks run in this tab, and the token never leaves your machine.
That is the point rather than a feature. An unexpired token is a working session, so a decoder hosted on someone else's server is asking you to send it your account and take a promise on trust. If you have already pasted a production token into one, treat it as disclosed and rotate it.
Findings
Paste a token on the left. Results appear as you type.
What a JWT actually protects
A signed JWT proves that a set of claims was issued by the holder of a key and has not been altered since. It does not make those claims private: the payload is base64url, which is an encoding and not a cipher, so anyone who obtains the token reads every claim in it without any key at all.
Almost every serious JWT failure follows from confusing those two properties, or from trusting the token to describe how it should be validated. The checks here come from RFC 8725, JWT Best Current Practices, with the claim definitions in RFC 7519.
What this does not do
It does not verify the signature. Verifying needs the key, and a tool that asked you for your signing key would be a worse thing to trust than the one you are already trying to inspect.
So a clean result describes the token, not the system. It cannot see whether your verifier pins the algorithm, checks the audience, honours the expiry or protects its keys, and those are where the exploitable bugs live. Read it as a statement about what you are handing out, then go and read the validation code.
Questions
- Is my token sent anywhere?
- No. The decoding and every check are plain functions running in your browser tab, with no request to any server at any point. This matters more for a token than for anything else you could paste into a tool, because an unexpired token is a working session: whoever receives it can act as you until it expires. If you have already pasted a production token into a hosted decoder, treat it as disclosed and rotate it.
- Why does this not verify the signature?
- Verifying requires the key, so a tool that verified for you would have to ask for your signing key, which is a worse thing to hand over than the token. Everything checked here is readable from the token itself: the algorithm, the claims, the lifetime and what the payload discloses. Signature verification belongs in your service, against a key it already holds.
- Is the payload of a JWT encrypted?
- No, and this is the most expensive misunderstanding in the format. A JWS payload is base64url, which is an encoding, not a cipher: anyone holding the token reads every claim in it with no key at all. The signature proves the claims were not altered, not that they are private. Encryption is a different construction, JWE, with five parts instead of three.
- How long should an access token live?
- Minutes. The lifetime is the window in which a stolen token still works, and there is no way to shorten it after the fact unless you can revoke, which most deployments cannot. The long life belongs to a refresh token, which is stored in one place, sent rarely and can be revoked without invalidating everyone.
- Is HS256 insecure?
- Not by itself. It is a key distribution problem: with a symmetric algorithm, every party able to verify a token is also able to mint one, so the moment the secret is shared with a second service, that service can issue tokens for any user. It is also the precondition for algorithm confusion, where an attacker replays a public RSA key as an HMAC secret. Asymmetric signing, RS256 or ES256 or EdDSA, removes both.
The claims side of this sits inside a wider list in the OWASP API Security Top 10 checklist, the same reasoning applied to an image instead of a token is in the Dockerfile checker, and PeakCore Auth is what these decisions look like inside an identity provider that issues tokens rather than inspects them.