JWT 算法 NONE 漏洞如何防御避免被伪造令牌?

文章导读
防御 JWT 算法 NONE 漏洞的核心是在服务端验证逻辑中显式指定允许的签名算法,并拒绝 alg 为 none 的令牌。适用于所有使用 JWT 进行身份认证的后端服务,风险边界在于旧版本库可能默认允许 none 算法。
📋 目录
  1. 快速处理思路
  2. 为什么会这样
  3. 分步处理
  4. 怎么验证是否生效
  5. 常见坑
  6. 常见问题
  7. 参考来源
A A

防御 JWT 算法 NONE 漏洞的核心是在服务端验证逻辑中显式指定允许的签名算法,并拒绝 alg 为 none 的令牌。适用于所有使用 JWT 进行身份认证的后端服务,风险边界在于旧版本库可能默认允许 none 算法。

先说结论:必须在代码中强制指定验证算法白名单,禁止接受 alg 为 none 的令牌,并升级 JWT 处理库到最新稳定版本。

  • 先判断:检查当前使用的 JWT 库版本及默认配置是否允许 alg:none
  • 优先做:在验证函数中显式传入 allowedAlgorithms 参数,仅信任 HS256 或 RS256 等具体算法
  • 再验证:使用篡改过 header 的令牌发起请求,确认服务端返回 401 或验证失败

快速处理思路

不同语言环境的 JWT 库配置方式不同,但核心动作都是在验证阶段限制算法。以下是常见环境的配置示例,直接替换原有验证逻辑。

Node.js (jsonwebtoken):

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

Python (PyJWT):

jwt.decode(token, key, algorithms=['HS256'])

Java (jjwt):

Jwts.parser().setSigningKey(key).parseClaimsJws(token);

注意不要使用不指定 algorithms 参数的重载方法,避免库默认行为导致漏洞。

为什么会这样

JWT 漏洞产生的原因是服务端盲目信任令牌 header 中声明的算法。JWT 结构包含 header、payload 和 signature,header 中定义了 alg 字段。攻击者将 alg 改为 none 并移除签名部分,如果服务端代码没有强制校验算法类型,就会跳过签名验证步骤,直接信任 payload 内容。公开资料中没有看到可靠的量化数据说明具体受影响版本比例,但多数旧版本库存在此默认行为。

分步处理

按以下顺序修复代码并部署,每一步都需要确认配置已生效。

步骤 1:排查依赖版本

检查项目依赖文件(如 package.json、requirements.txt、pom.xml),确认 JWT 库版本。如果版本发布时间较早,优先升级到官方推荐的最新稳定版。升级前阅读变更日志,确认是否修复了算法混淆相关漏洞。

步骤 2:修改验证代码

找到所有调用 JWT 验证函数的位置。删除不指定算法参数的调用方式,显式添加 algorithms 或 allowedAlgorithms 参数。只填入业务实际使用的算法,例如仅使用 HS256 就只填 ['HS256']。不要使用 ['none'] 或空列表。

步骤 3:配置回滚方案

JWT 算法 NONE 漏洞如何防御避免被伪造令牌?

修改验证逻辑可能导致旧令牌失效。确认业务是否支持强制用户重新登录。如果不支持,需准备临时兼容方案,但必须在日志中记录所有 alg:none 的请求以便监控。

怎么验证是否生效

修复完成后,必须通过攻击模拟验证防御是否生效。

验证动作:使用 JWT 调试工具或脚本,生成一个 header 中 alg 为 none 且没有签名部分的令牌,payload 中包含管理员权限 claims。

预期结果:服务端接口应返回 401 Unauthorized 或 403 Forbidden,日志中应记录签名验证失败或算法不支持的错误。

检查位置:查看应用日志文件或监控平台,搜索 verify failed、invalid algorithm 或 signature mismatch 关键词。

常见坑

修复过程中容易忽略以下细节,导致防御失效。

1. 默认配置陷阱:部分库在不传参数时默认允许所有算法,包括 none。必须显式传递白名单。

2. 算法混淆攻击:即使禁止了 none,如果服务端同时支持 HS256 和 RS256,攻击者可能用公钥验证 HS256 签名。建议服务端固定单一算法类型。

3. 中间件覆盖:某些网关或认证中间件可能独立处理 JWT,代码层修复后需同步检查网关配置。

常见问题

JWT 库升级后需要重新签发所有令牌吗?

通常不需要,只要签名密钥不变且算法未变更,旧令牌仍可验证。但如果修复涉及密钥轮换或算法变更,则需用户重新登录。

为什么不能直接在前端禁止 alg:none?

前端代码完全可控,攻击者可绕过前端直接构造请求。所有安全验证必须在服务端执行,前端限制无效。

使用 HTTPS 是否能防止 JWT 算法 NONE 漏洞?

不能。HTTPS 仅保护传输链路加密,无法防止攻击者拿到令牌后篡改 header 内容重放请求。

参考来源

  • OWASP Cheat Sheet Series, JSON Web Token for Java Cheat Sheet, https://cheatsheetseries.owasp.org/cheatsheets/JSON_Web_Token_for_Java_Cheat_Sheet.html
  • Auth0 Blog, 10 Common JWT Security Mistakes, https://auth0.com/blog/10-common-jwt-security-mistakes/