JWT 算法 “none” 攻击:仅一行代码的漏洞

发布: (2025年12月31日 GMT+8 13:53)
3 min read
原文: Dev.to

Source: Dev.to

攻击演示

// ❌ This looks fine...
const decoded = jwt.verify(token, secret, {
  algorithms: ['HS256', 'none'], // 💀 The vulnerability
});

1. 攻击者获取一个有效的 JWT

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiIxMjM0NTYiLCJyb2xlIjoidXNlciJ9.
signature_here

2. 将头部修改为 none 算法

eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.
eyJzdWIiOiIxMjM0NTYiLCJyb2xlIjoiYWRtaW4ifQ.
// No signature needed!

3. 服务器因为在算法列表中包含 "none" 而接受了它

攻击者现在是管理员。

已知 CVE

CVE问题
CVE-2015-2951jwt‑simple算法混淆
CVE-2016-10555jose2gonone 算法绕过
CVE-2018-0114node‑jose密钥混淆

安全配置示例

// ✅ 明确白名单算法
const decoded = jwt.verify(token, secret, {
  algorithms: ['HS256'], // 只使用你需要的!
});
// ❌ 危险:允许 "none"
jwt.verify(token, secret, { algorithms: ['none'] });
// ✅ 安全:显式 RS256 验证
jwt.verify(token, publicKey, { algorithms: ['RS256'] });
// ❌ 危险:可被暴力破解的密钥
jwt.sign(payload, 'password123');
// ✅ 安全:强密钥(256+ 位)
jwt.sign(payload, process.env.JWT_SECRET);
// ❌ 危险:令牌永不过期
jwt.sign({ userId: 123 }, secret);
// ✅ 安全:短期过期时间
jwt.sign({ userId: 123 }, secret, { expiresIn: '1h' });
// ❌ 危险:在令牌中存放密码(令牌可以被解码!)
jwt.sign({ userId: 123, password: 'secret' }, key);
// ✅ 安全:仅在负载中放置 ID
jwt.sign({ userId: 123 }, key);

JWT 安全的 ESLint 插件

eslint-plugin-jwt 规则集强制最佳实践并捕获常见陷阱。

规则概览

规则CWE检测内容
no-algorithm-noneCWE‑347允许 "none" 算法
no-algorithm-confusionCWE‑327RS/HS 混淆攻击
no-weak-secretCWE‑326可被暴力破解的密钥
no-hardcoded-secretCWE‑798代码中硬编码的密钥
no-sensitive-payloadCWE‑312令牌中包含个人敏感信息
require-expirationCWE‑613缺失 exp 声明
require-algorithm-whitelistCWE‑327未显式指定算法列表
require-issuer-validationCWE‑345缺失 iss 校验
require-audience-validationCWE‑345缺失 aud 校验
no-decode-without-verifyCWE‑347错误使用 jwt.decode()
require-issued-atCWE‑613缺失 iat 声明
require-max-ageCWE‑613verify 中缺少 maxAge 参数
no-timestamp-manipulationCWE‑345时钟偏移利用

示例 lint 错误

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']

安装

npm install eslint-plugin-jwt
// .eslintrc.js
import jwtPlugin from 'eslint-plugin-jwt';

export default [jwtPlugin.configs.recommended];

13 条规则。完整的 JWT 安全。零误报。
⭐ 在 GitHub 上点星。

立即行动

🚀 现在检查你的 JWT 配置。你的算法列表中是否包含 "none"

GitHub | LinkedIn

Back to Blog

相关文章

阅读更多 »