JWT security pitfalls: algorithm confusion and none attack
alg:none attack, algorithm confusion RS256 vs HS256, explicit algorithm whitelisting in verify, key confusion vulnerability, CVE examples, secure defaults
JWT Security Pitfalls: Algorithm Confusion and the None Attack
JWTs have two famous vulnerabilities that are still found in production systems.
The alg:none attack: The JWT spec originally allowed alg: "none" to indicate an unsigned token. Some libraries honored this โ an attacker could strip the signature, change the payload to any user ID, set alg: "none", and the library would accept it.
Fix: always pass the allowed algorithms explicitly to jwt.verify:
// WRONG โ library might accept alg:none or unexpected algorithms
jwt.verify(token, secret);
// CORRECT โ whitelist exactly what you sign with
jwt.verify(token, secret, { algorithms: ['HS256'] });Algorithm confusion (RS256 โ HS256): If your server uses RS256 (asymmetric โ private key signs, public key verifies), an attacker can take your public key, forge a token signed with it using HS256 (symmetric โ same key signs and verifies), and a naive library will accept it because the "key" matches.
Fix: same solution โ specify algorithms: ['RS256'] in verify. Never let the token header dictate the algorithm used for verification.
These are not theoretical. CVEs for both exist in major libraries. The fix in every case is one line: whitelist the algorithm. Do it on every project.
