Common JWT Security Mistakes Developers Should Avoid
A developer checklist for JWT algorithms, expiry, issuer, audience, signature verification, token storage, and safe debugging.
Maintained by Ali Aygör. Report a correction.
Readable claims are not authenticated claims
A browser decoder can read a JWT header and payload without possessing a trusted verification key. A modified payload can still parse perfectly. Treat everything displayed by a decoder as untrusted until the server verifies the signature and applies its configured token policy.
This site's inspector reports claim checks, not signature validity. A not-expired label only describes the decoded timing value relative to the device clock. It must never be used as a client-side authorization decision.
Test expiry and not-before separately
Use a synthetic fixture with exp in the past and another with nbf in the future. Confirm that the application rejects them according to its verifier policy. NumericDate values use seconds, so a millisecond value can accidentally create a wildly incorrect lifetime.
A missing exp needs a policy decision; it is not automatic proof that a token is valid forever. Define any clock tolerance deliberately rather than repeatedly extending expiry to compensate for an unexplained clock mismatch.
{
"iss": "https://auth.example.com",
"aud": ["api", "reports"],
"nbf": 1700000000,
"exp": 1700003600
}
// Synthetic claims only; no signature is provided.Check issuer and audience in the verifier
An audience may be a string or an array of strings. The expected recipient must match the appropriate value. Testing only the string form can reject valid array-based tokens or leave a gap when the application makes assumptions about the representation.
An issuer string in an unverified payload is not proof of identity. Configure trusted issuers and their keys outside the token itself, then test an otherwise plausible token with an unexpected issuer or audience.
Avoid algorithm conclusions based only on a header
An alg=none token is unsigned and needs an explicitly designed trusted use case if it is accepted at all. The server should verify using permitted algorithms and trusted key material. It should not select an arbitrary trust policy from attacker-controlled header text.
HS256 is not inherently broken merely because it uses a shared secret. Its safety depends on a strong secret, appropriate distribution and correct verification. Similarly, an asymmetric algorithm name alone does not prove correct key lookup or signature validation.
Keep real credentials out of debugging artifacts
Prefer synthetic or revoked test tokens when checking a decoder. Active bearer tokens can be replayable credentials even when the claims appear harmless. Redact them from screenshots, tickets and repository fixtures.
Test the server's rejection paths as well as a legitimate token. A decoder is useful for diagnosing representation and claim mismatches; the server's verifier and authorization tests are the evidence that the access decision is correct.
Specifications and references
Continue the investigation
How to convert Unix timestamp to date
Convert Unix seconds or milliseconds into readable dates and understand timezone differences in API logs and JWT claims.
How to decode a JWT token
Learn how to decode JWT header and payload claims in the browser, read exp and iat values, and avoid common token mistakes.
How to encode and decode Base64
Understand Base64 encoding, decode strings safely in the browser, and connect decoded output to JSON, JWT, and file workflows.
Related tools
API & Auth
OpenJWT Security Inspector
Decode JWTs, inspect expiry, issuer, audience, algorithm choices, and common token security mistakes.
API & Auth
OpenJWT Decoder
Decode JWT headers and payloads, inspect claims, and check expiry fields at a glance.
API & Auth
OpenHeader Parser
Parse raw HTTP headers into readable key and value pairs for request and response debugging.