
JWT Pitfalls Cheat Sheet
alg=none, weak HS256 secrets, kid abuse, and the validation must-haves your auth gateway needs to enforce.
What are the most common JWT security mistakes?
The recurring JWT failures are trusting the token's own alg header, skipping signature verification entirely, not checking issuer, audience, and expiry, using weak or shared signing secrets, and treating unverified claims as authorization. Macksofy tests each of these in API and web application penetration tests.
JSON Web Tokens are simple to implement and easy to break. This cheat sheet lists the pitfalls we keep finding across BFSI, fintech and SaaS pentests — with the must-haves your auth gateway should enforce on every request.
The big six pitfalls
| Pitfall | Why it ships | What to enforce |
|---|---|---|
| alg=none accepted | Default JWT libs accept it | Reject all tokens where alg ∈ {none, None, NONE} |
| HS256 with weak secret | Dev seed copy-pasted into prod | ≥ 256-bit random secret; rotation policy |
| Algorithm confusion (HS256 ↔ RS256) | Validator picks alg from token header | Pin the expected alg server-side; never trust header alg |
| kid path traversal / SQLi | kid value used as filename / SQL parameter | Whitelist kid → key; never use kid in I/O |
| Forever-valid tokens | exp claim missing or far-future | Enforce short exp + refresh-token model |
| Replay after revoke | Stateless design with no server denylist | Maintain server-side revocation list keyed by jti |
Validation must-haves on every request
- Pinned algorithm (server picks, not the token)
- Cryptographic signature verification
- Issuer (iss) match
- Audience (aud) match
- Expiry (exp) check with no clock-skew tolerance > 60s
- Not-before (nbf) check if used
- Revocation check against server denylist (jti)
- Rate-limit on validation failures
Quick decisions
- Sessions are simpler. If a JWT-stateful design forces you to maintain server state anyway, prefer plain sessions.
- Short-lived access tokens + opaque refresh tokens is the safe default for OAuth flows.
- Don't put PII in the JWT body — assume the token will be logged somewhere it shouldn't be.
- Encrypt (JWE), don't just sign (JWS), if the body must contain sensitive claims.
Across 2025 pentests we found alg=none accepted in 3 of every 10 BFSI / fintech engagements — almost always on a sidecar service, not the main login. Audit every service that validates JWTs, not just the customer-facing one.
Macksofy offers full-service engagements that map directly to this resource. Common starting points:
