KitJade

Security 6 min read

JWT decoding is not verification: what each step actually proves

Published Updated By the KitJade editorial team

A JSON Web Token is three Base64URL-encoded parts separated by dots: header, payload and signature. Anyone holding the token can read the first two. That is not a vulnerability; it is the design. JWTs are signed, not encrypted.

The dangerous mistake is treating a readable payload as a trusted one. A decoder shows you what a token claims. Only signature verification, performed with the right key and algorithm, tells you who issued it and whether it was altered.

What each part contains

The header typically names the signing algorithm and token type. The payload holds claims such as subject, issuer, expiry and custom roles. The signature is computed over the header and payload using a key that only the issuer should hold.

A decoder is a convenience for inspecting claims during development. It cannot tell you whether the signature is valid, because it does not have the verification key — and even if it did, doing verification in the browser would expose that key to every visitor.

The algorithm confusion trap

Older libraries sometimes accepted the algorithm named in the token header. An attacker could switch an RS256 token to HS256 and sign it using the public key as an HMAC secret. Modern libraries require you to specify the accepted algorithms explicitly; do that.

The same principle applies to key IDs: never fetch a key from an attacker-controlled URL just because the token's kid header points there.

Claims that still need checking

A valid signature proves integrity and origin, not freshness or audience. Check exp (expiry), nbf (not before), iss (issuer) and aud (audience). Clock skew should be small and deliberate, not an hour of tolerance added to make tests pass.

If a token carries roles, enforce them server-side. A role claim is only as trustworthy as the service that signed the token.

When decoding is enough

Decoding is the right tool for debugging: confirming which scopes were requested, checking whether exp is in the past, or explaining why a gateway rejected a request. Use it to understand the token, then verify it where the decision is made.

Frequently asked questions

Can a JWT payload be encrypted?
Yes, using JWE (JSON Web Encryption). A JWE has five parts instead of three and its payload is ciphertext. A normal three-part JWS token is only signed, so its claims are readable by anyone who has the token.
Is it safe to paste a production JWT into a decoder?
Prefer a decoder that runs locally in the browser, and avoid pasting long-lived production tokens into any page you do not trust. Even with local processing, a compromised browser extension can read what is on screen.

Put it into practice