Interlace ESLint
ESLint Interlace

no-algorithm-none

**Severity:** � Critical

Disallow JWT "none" algorithm which bypasses signature verification (CVE-2022-23540)

Severity: 🔴 Critical
CWE: CWE-347
CVE: CVE-2022-23540

Rule Details

This rule detects attempts to use the none algorithm which completely bypasses JWT signature verification. An attacker can forge any JWT payload and it will be accepted.

Examples

❌ Incorrect

// Direct 'none' algorithm
jwt.verify(token, secret, { algorithm: 'none' });

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

// Mixed with other algorithms
jwt.verify(token, secret, { algorithms: ['RS256', 'none'] });

// Case variations
jwt.verify(token, secret, { algorithm: 'NONE' });
jwt.verify(token, secret, { algorithm: 'None' });

// Empty algorithms array
jwt.verify(token, secret, { algorithms: [] });

✅ Correct

// Explicit secure algorithm
jwt.verify(token, secret, { algorithms: ['RS256'] });

// Multiple secure algorithms
jwt.verify(token, secret, { algorithms: ['RS256', 'ES256'] });

// HMAC with strong secret
jwt.verify(token, secret, { algorithms: ['HS256'] });

Options

{
  "jwt/no-algorithm-none": ["error", {
    "allowInTests": false
  }]
}
OptionTypeDefaultDescription
allowInTestsbooleanfalseAllow in test files

When Not To Use It

Never disable this rule in production code. You may use allowInTests: true for security testing.

Known False Negatives

The following patterns are not detected due to static analysis limitations:

Dynamic Algorithm Configuration

Why: The rule checks for literal 'none' strings, not dynamically constructed values.

// ❌ NOT DETECTED - Variable contains 'none'
const algo = getAlgorithmFromConfig(); // Returns 'none'
jwt.verify(token, secret, { algorithm: algo });

Mitigation: Use TypeScript strict typing for algorithm options. Implement runtime validation.

Spread Operator Options

Why: Spread objects are not statically analyzable.

// ❌ NOT DETECTED - Algorithm in spread object
const maliciousOptions = { algorithm: 'none' };
jwt.verify(token, secret, { ...maliciousOptions });

Mitigation: Avoid spreading untrusted option objects. Validate options at runtime.

External Configuration Files

Why: ESLint cannot trace values from JSON/YAML config files.

// ❌ NOT DETECTED - Algorithm from config file
// config.json: { "jwt": { "algorithm": "none" } }
import config from './config.json';
jwt.verify(token, secret, { algorithm: config.jwt.algorithm });

Mitigation: Validate configuration at application startup. Use schema validation for config files.

Library Wrapper Defaults

Why: Default options set inside wrapper functions are not visible.

// ❌ NOT DETECTED - Wrapper function with unsafe defaults
function verifyToken(token: string) {
  // 'none' hardcoded in wrapper
  return jwt.verify(token, secret, { algorithms: ['none', 'HS256'] });
}
verifyToken(userToken); // Looks safe, but isn't

Mitigation: Apply this rule to all files including utility modules.

Further Reading

On this page