DEV Community

Cover image for Exploit Analysis: The JWT Algorithm 'none' Attack (And the Guard)
Ofri Peretz
Ofri Peretz

Posted on • Edited on • Originally published at ofriperetz.dev

Exploit Analysis: The JWT Algorithm 'none' Attack (And the Guard)

A single line of configuration can forge a JWT. Here is the technical analysis of the 'none' algorithm attack, and the automated static analysis guard that eliminates this architectural risk.

JWT authentication is everywhere. It's also one of the most misconfigured security mechanisms.

One line of code can compromise everything.

The Vulnerable Code

// ❌ This looks fine...
const decoded = jwt.verify(token, secret, {
  algorithms: ['HS256', 'none'], // πŸ’€ The vulnerability
});
Enter fullscreen mode Exit fullscreen mode

The Attack

// 1. Attacker takes a valid JWT:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiIxMjM0NTYiLCJyb2xlIjoidXNlciJ9.
signature_here

// 2. Modifies the header to use "none" algorithm:
eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.
eyJzdWIiOiIxMjM0NTYiLCJyb2xlIjoiYWRtaW4ifQ.
// No signature needed!

// 3. Server accepts it because "none" is in algorithms list
// Attacker is now admin
Enter fullscreen mode Exit fullscreen mode

Real CVEs

CVE Library Impact
CVE-2015-2951 jwt-simple Algorithm confusion
CVE-2016-10555 jose2go None algorithm bypass
CVE-2018-0114 node-jose Key confusion

The Fix

// βœ… Explicitly whitelist algorithms
const decoded = jwt.verify(token, secret, {
  algorithms: ['HS256'], // Only what you use!
});
Enter fullscreen mode Exit fullscreen mode

All JWT Vulnerabilities

1. Algorithm None

// ❌ Dangerous
jwt.verify(token, secret, { algorithms: ['none'] });

// βœ… Safe
jwt.verify(token, secret, { algorithms: ['HS256'] });
Enter fullscreen mode Exit fullscreen mode

2. Algorithm Confusion

// ❌ Dangerous: RS256 token verified with symmetric secret
jwt.verify(token, publicKey);

// βœ… Safe: Explicit algorithm
jwt.verify(token, publicKey, { algorithms: ['RS256'] });
Enter fullscreen mode Exit fullscreen mode

3. Weak Secret

// ❌ Dangerous: Brute-forceable
jwt.sign(payload, 'password123');

// βœ… Safe: Strong secret
jwt.sign(payload, process.env.JWT_SECRET); // 256+ bits
Enter fullscreen mode Exit fullscreen mode

4. Missing Expiration

// ❌ Dangerous: Token valid forever
jwt.sign({ userId: 123 }, secret);

// βœ… Safe: Short expiration
jwt.sign({ userId: 123 }, secret, { expiresIn: '1h' });
Enter fullscreen mode Exit fullscreen mode

5. Sensitive Payload

// ❌ Dangerous: Password in token (tokens can be decoded!)
jwt.sign({ userId: 123, password: 'secret' }, key);

// βœ… Safe: Only IDs
jwt.sign({ userId: 123 }, key);
Enter fullscreen mode Exit fullscreen mode

ESLint Coverage

// eslint.config.js
import jwtPlugin from 'eslint-plugin-jwt';

export default [jwtPlugin.configs.recommended];
Enter fullscreen mode Exit fullscreen mode

13 JWT Rules

Rule CWE What it catches
no-algorithm-none CWE-347 Algorithm "none" allowed
no-algorithm-confusion CWE-327 RS/HS confusion attacks
no-weak-secret CWE-326 Brute-forceable secrets
no-hardcoded-secret CWE-798 Secrets in code
no-sensitive-payload CWE-312 PII in tokens
require-expiration CWE-613 Missing exp claim
require-algorithm-whitelist CWE-327 No explicit algorithms
require-issuer-validation CWE-345 Missing iss check
require-audience-validation CWE-345 Missing aud check
no-decode-without-verify CWE-347 jwt.decode() misuse
require-issued-at CWE-613 Missing iat claim
require-max-age CWE-613 No maxAge in verify
no-timestamp-manipulation CWE-345 Clock skew exploits

Error Messages

src/auth.ts
  15:3  error  πŸ”’ CWE-347 CVSS:9.8 | JWT algorithm 'none' is allowed
               Risk: Attackers can forge tokens without a signature
               Fix: Remove 'none' from algorithms: ['HS256']
Enter fullscreen mode Exit fullscreen mode

Quick Install

::dev-to-cta{url="https://npmjs.com/package/eslint-plugin-jwt in 60 seconds. 13 rules. Full JWT security. Zero false positives.**


πŸ“¦ npm: eslint-plugin-jwt
πŸ“– Rule: no-algorithm-none

⭐ Star on GitHub


The Interlace ESLint Ecosystem
Interlace is a high-fidelity suite of static code analyzers designed to automate security, performance, and reliability for the modern Node.js stack. With over 330 rules across 18 specialized plugins, it provides 100% coverage for OWASP Top 10, LLM Security, and Database Hardening.

Explore the full Documentation

Β© 2026 Ofri Peretz. All rights reserved.


Build Securely.
I'm Ofri Peretz, a Security Engineering Leader and the architect of the Interlace Ecosystem. I build static analysis standards that automate security and performance for Node.js fleets at scale.

ofriperetz.dev | LinkedIn | GitHub

Top comments (0)