HOME / FREE TOOLS / JWT DECODER

JWT decoder. Header, payload, expiry.

Paste a token to read what is inside it and whether it has expired. The signature is not verified — that needs your secret, which should never leave your machine.

RUNNING LOCALLY
HEADER
PAYLOAD

What a JWT actually is

A JSON Web Token is three chunks of Base64url separated by dots. Header, payload, signature. The first two are not encrypted — they are encoded, which is a different thing entirely, and anyone holding the token can read them. That is what the tool above does.

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9  .  eyJzdWIiOiIxMjM0NSIsImV4cCI6MTc2NzIyNTYwMH0  .  SflKxwRJSMeKKF2QT4f
└────────── header ──────────┘     └──────────── payload ────────────┘     └──── signature ────┘
Three parts, two of them readable by anyone
If you have ever put something in a JWT payload because "it is encoded", paste that token above. Anything you can read there, so can whoever holds the token.

Two fields matter. typ is almost always JWT. alg is the one worth reading, because it is where the classic vulnerability lives.

  • HS256 — signed with a shared secret. Whoever can verify can also sign.
  • RS256 / ES256 — signed with a private key, verified with a public one. Use this when the verifier should not be able to mint tokens.
  • none — no signature. A token claiming this should never be accepted, and a library that honours it has a known vulnerability class named after it.

The algorithm confusion attack

If a server verifies with RS256 but a library lets an attacker resubmit the token as HS256, the public key — which is public — becomes the shared secret, and the attacker can sign anything. The fix is to pin the expected algorithm rather than trusting the one in the header. Never let the token tell you how to verify the token.

The payload, and the claims worth checking

The payload is a JSON object. Seven of its field names are registered and mean the same thing everywhere:

  • exp — expiry, as a Unix timestamp. The tool above shows whether it has passed.
  • iat — issued at. Useful for spotting a token minted far longer ago than you expected.
  • nbf — not before. The token is invalid until this time.
  • sub — the subject, usually a user id.
  • iss — who issued it. Check this if you accept tokens from more than one source.
  • aud — the intended audience. A token for one service being accepted by another is a real bug and this claim is how you stop it.
  • jti — a unique id, for revocation lists.

Why this tool does not verify the signature

Verifying means recomputing the signature, which needs the secret or public key. Pasting a production signing secret into a web page is the sort of thing that ends up in a breach write-up, so this tool does not ask for one and could not use it if you gave it — nothing here leaves your browser.

Decoding tells you what a token claims. Verifying tells you whether to believe it. Do the second one on your server, with a library, against a key you pinned.

Four mistakes worth checking for

  • Secrets in the payload. Decode your own tokens and look. Email addresses and internal ids are common; API keys happen more often than anyone admits.
  • No expiry. A token with no exp is valid forever unless you maintain a revocation list, and almost nobody does.
  • Expiry measured in months. A leaked token is valid until it expires. That window is your exposure.
  • Storing it in localStorage. Any cross-site scripting on your page can read it. An httpOnly cookie cannot be read by script.

Finding these in a codebase

Reading one token by hand is useful; checking every place your code signs, verifies or stores one is a different job. Spartyx flags hardcoded signing secrets, tokens committed to source, and JWT handling that skips verification — across a whole repository rather than one paste.

Scan a public repository free, no account needed.

Need more than a single check?

Spartyx scans a whole repository — cross-file taint tracking, dependency CVEs and a PDF report. Free during beta.