Analysing a JWT for Security Problems: Algorithms, Expiry and Trust

A JSON Web Token is a compact way for one service to assert something about a user or a session, and for another service to trust that assertion by checking its signature. The token has three parts, separated by dots: a header naming the algorithm, a payload carrying claims such as the subject and expiry, and a signature computed over the first two parts. The JWT Security Analyzer reads a token you paste in, decodes its header and payload, and flags structural and configuration problems, in your browser, without contacting a server. It analyses the text you supply; it cannot verify a signature without the right key, and it cannot prove that a token is trustworthy, since a well-formed token can still carry a false claim.

The classic flaws are worth learning by name, because they recur. The none algorithm means a token claims to need no signature at all, and any verifier that accepts it will trust unsigned tokens. Algorithm confusion means a verifier can be tricked into checking a token with the wrong kind of key, such as using a public key as if it were a shared secret. A missing expiry claim means a token never expires on its own, so a leaked token remains usable until someone explicitly revokes it. Weak signing, such as a short or guessable secret, means the signature can be forged by anyone who guesses the secret. Each flaw is a property of the token and its verifier together, and the analyser flags the token side so the verifier side can be fixed.

How it works

An analyser typically decodes the header and payload from their base64url encoding, lists the claims in readable form, and runs a set of checks: is the algorithm present and on an approved list, is an expiry claim present and in the future, is the token's lifetime reasonable, and are sensitive claims, such as administrative roles, present in a form that should not be trusted blindly? Some analysers also check the signature structure, such as whether a signature is present at all, though a full verification needs the correct key and algorithm. The output is a list of findings, each of which deserves a human decision about whether it matters for that particular system.

The handling rule for real tokens is absolute: never paste a production token into an analyser, a ticket, a chat message or any tool outside the system that issued it. A token is a credential, and pasting it anywhere it does not belong should be treated as exposure. Analyse with sample tokens that mimic the structure of real ones, or with tokens issued specifically for testing, and keep real tokens inside the systems that own them. If a real token has been pasted somewhere it should not be, revoke it and issue a replacement rather than hoping nobody copied it.

Where it goes wrong

The most common analysis error is treating a clean analyser report as proof of security. An analyser sees the token, not the verifier, and a verifier with a flawed configuration can accept tokens the analyser would flag, or reject tokens it would pass. Another error is checking the header but ignoring the payload, where overly broad claims or sensitive data may sit in plain readable form; token payloads are encoded, not encrypted, and anyone with the token can read them. A third is ignoring clock skew, where a token that looks expired or not-yet-valid may simply reflect clocks that disagree. Finally, never embed secrets in a token's payload, since every holder of the token can decode and read them.

Worked example

Worked example with sample values. Suppose you paste a sample token with 3 parts: a header, a payload and a signature. The header names 1 algorithm, the payload carries 5 claims: subject, issuer, issued-at, expiry and role, which is 5 claims. The analyser runs 4 checks: algorithm approved, expiry present, lifetime reasonable, and signature present. It reports 1 finding: the lifetime is 24 hours, which is 24 times 60, which is 1440 minutes, longer than the sample policy of 60 minutes, so the token exceeds the policy by 1440 minus 60, which is 1380 minutes. The other 3 checks pass, giving 3 passes out of 4 checks, or 75 percent passing. The fix is to shorten the lifetime to 60 minutes, which would make all 4 checks pass. These are sample values for illustration, using a test token, not a real credential, and the arithmetic shows how a finding becomes a concrete change.

Mistakes to avoid

One mistake is rotating a signing key without updating every verifier, which turns a security improvement into an outage. Another is trusting claims in an unverified token, such as reading a role from a token whose signature was never checked, which is equivalent to trusting the caller's word. A third is logging full tokens in application logs, where they persist for months and can be replayed. Log token identifiers or truncated forms, never full tokens, and keep signature verification mandatory in every verifier, without exception for internal traffic.

Putting it into practice

Use the analyser during development and review, with test tokens only. Paste a sample token, read every finding, and fix the token issuer or verifier configuration that caused it, rather than editing the sample to hide the finding. Record the approved algorithm list and the maximum lifetime as policy, and re-analyse whenever either changes. When a real token is suspected of exposure, revoke it first and investigate second, because a revoked token cannot be replayed while you work out what happened. That order protects users while the analysis continues.

Related tools and reading: the JWT Decoder and the Hash Generator cover neighbouring checks that pair naturally with this one, and the guide at [/blog/jwt-decoder-guide/] extends the same topic with further background and examples for readers who want to go deeper.

Key points

  • A JWT has header, payload and signature, separated by dots
  • The none algorithm and algorithm confusion are classic flaws
  • A token without expiry stays valid until it is revoked
  • Never paste a real production token into any analyser

In short: A JWT is a header, a payload and a signature, and its security depends on the algorithm, the expiry and the verifier together. Analyse test tokens for classic flaws, never paste real tokens anywhere, and fix the issuer or verifier rather than the sample.

One habit ties all of this together: re-check after every change. A result is only as current as the input it was run on, so a fix, a redesign, or a new version of the underlying material deserves a fresh run rather than reliance on an old report. Keep the previous result alongside the new one, note what changed between them, and treat any new finding as a question to investigate rather than a verdict to accept or dismiss. That loop of checking, fixing, re-checking and recording is what turns a one-off test into a reliable routine, and it costs far less time than debugging a problem that a second check would have caught early.