arrow_backBack to Guides
Aug 10, 2026·Security

The 5 Most Common JWT Security Flaws

The Illusion of Security

JSON Web Tokens are cryptographically secure by design. The mathematics behind HMAC, RSA, and ECDSA signatures are practically unbreakable. However, the implementation of JWTs within application code is notoriously fragile. Most JWT breaches are not due to broken cryptography, but due to human error and library misconfiguration. Here are the five most dangerous vulnerabilities you must actively guard against.

1. Algorithm Confusion Attacks

This is arguably the most famous JWT vulnerability. Suppose your server expects an asymmetric RSA signature (RS256). An attacker takes a valid token, changes the header to specify a symmetric HMAC signature (HS256), and then signs the token using your server's public RSA key (which is often freely available). If your backend library blindly trusts the algorithm in the header, it will use the public key as an HMAC secret, successfully verify the forged signature, and grant the attacker access. Fix: Always hardcode the expected algorithm in your verifier, explicitly telling it to reject any token that doesn't use the pre-approved algorithm.

2. Permitting the "none" Algorithm

As mentioned in other guides, the JWT specification includes a "none" algorithm for situations where the token has already been verified by a secure channel. If a library allows this algorithm to pass through in a production environment, attackers can simply strip the signature entirely and forge any payload they want. Fix: Strictly prohibit the none algorithm in your backend configuration.

3. Weak HMAC Secrets

If you use a symmetric algorithm (HS256), the security of every single token relies entirely on a single shared secret key. If that key is simply "secret123" or a short dictionary word, attackers can capture a token, take it offline, and brute-force the signature in minutes. Once they know the secret, they can forge admin tokens forever. Fix: Always use a strong, cryptographically random secret of at least 256 bits (32 bytes).

4. Exposing Sensitive Data in the Payload

A staggering number of developers mistakenly believe that because a JWT is signed and looks like gibberish, it is encrypted. JWTs are not encrypted. They are merely Base64URL encoded. Anyone with a web browser can decode the payload. Never, under any circumstances, put passwords, social security numbers, API keys, or sensitive Personally Identifiable Information (PII) in a JWT payload.

5. Insecure Client-Side Storage

Storing JWTs in the browser's LocalStorage or SessionStorage makes them incredibly vulnerable to Cross-Site Scripting (XSS) attacks. If an attacker manages to inject even a single line of malicious JavaScript into your application, they can easily read the token from LocalStorage and steal the user's session. Fix: The most secure place to store a JWT in a web browser is inside a strict, HttpOnly, Secure, SameSite cookie, which is completely invisible to JavaScript.