JSON Web Tokens are popular for good reason — they let a server verify who a user is without a database lookup on every request. That same self-contained design is also why a few specific implementation mistakes turn into complete authentication bypasses rather than minor bugs.
Mistake one: trusting the alg header
A JWT's header declares which algorithm was used to sign it. Some libraries, in early or misconfigured versions, will happily verify a token using whatever algorithm the token itself claims — including none, which some implementations treat as "no signature required." An attacker can take a legitimate token, change the payload (say, their user role from user to admin), set the algorithm header to none, strip the signature, and have it accepted. The fix is to always specify the expected algorithm explicitly on the verifying side, never read it from the token being verified.
Mistake two: confusing signing with encryption
A standard JWT is signed, not encrypted. Anyone who intercepts it can base64-decode the payload and read it in plaintext — they just can't modify it without invalidating the signature (assuming the algorithm check above is correct). Storing sensitive data like a password, a full credit card number, or private personal details directly in the payload is a common and avoidable mistake, because "the user can't tamper with it" doesn't mean "the user can't read it."
Mistake three: no expiry, or no revocation path
A JWT with no exp claim, or an unreasonably long one, is valid forever once issued. Because JWTs are stateless by design, there's no server-side session to invalidate the way there is with a traditional session cookie — if a token leaks, it stays usable until it expires on its own. Short expiry windows paired with a refresh-token flow (where the long-lived refresh token is tracked server-side and can be revoked) is the standard way to keep the stateless benefit without losing the ability to cut off a compromised session.
Mistake four: weak or hardcoded signing secrets
HMAC-based JWTs (HS256) are only as strong as the shared secret used to sign them. A short, guessable, or hardcoded-in-source secret can be brute-forced offline once an attacker has even one valid token to test guesses against. This is the same category of mistake as a hardcoded API key, with a worse consequence — recovering the secret means forging tokens for any user, including ones that don't exist yet.
Takeaway
JWTs push a lot of decisions that used to be the server's job onto the token format itself. That's the appeal, but it also means algorithm confusion, missing expiry, and weak secrets don't degrade gracefully — they tend to fail all the way open.