3. JWT 安全风险:无签名攻击、密钥泄露、算法混淆攻击(alg=none)、重放攻击
JSON Web Token(JWT)作为无状态认证的主流方案,其安全性高度依赖于实现过程的严谨性。在实际生产环境中,由于开发人员对 JWT 规范理解不深、库使用不当或配置疏忽,常导致严重的安全漏洞。本章将深入剖析四种最具破坏力的 JWT 攻击向量,并给出对应的防御策略。
3.1 攻击向量全景图
下表总结了四种核心攻击类型的攻击原理、利用条件与危害等级,帮助安全工程师建立全局风险视图。
| 攻击类型 | 攻击原理 | 利用条件 | 危害等级 |
|---|---|---|---|
| 无签名攻击 | 将 JWT 头部 alg 字段设为 none,绕过签名验证 |
服务端未强制校验签名算法,或允许 none 算法 |
严重 |
| 密钥泄露 | 攻击者获取签名密钥后,可伪造任意合法 Token | 密钥硬编码、泄露到版本控制、日志或配置中心 | 灾难性 |
| 算法混淆攻击 | 利用服务端对非对称/对称算法验证逻辑的缺陷,使用公钥作为 HMAC 密钥签名 | 服务端未校验算法类型与密钥的匹配关系 | 严重 |
| 重放攻击 | 截获合法 Token 后重复使用,绕过身份验证 | Token 缺乏一次性校验或时间窗口约束 | 中-高 |
3.2 无签名攻击(alg=none)
JWT 规范(RFC 7519)定义了一种特殊算法 none,用于在已通过其他通道(如 TLS)保证完整性的场景下跳过签名。然而,许多服务端实现错误地接受了 alg: none 的 Token,导致攻击者可以构造任意载荷而无需任何密钥。
{"alg":"HS256"} 修改为 {"alg":"none"},并将载荷中的 "role":"user" 改为 "role":"admin",然后移除签名部分。若服务端未做严格校验,将直接信任该 Token。
// 攻击者构造的恶意 JWT
// Header: {"alg":"none"}
// Payload: {"sub":"1234567890","name":"John Doe","role":"admin","iat":1516239022}
// Signature: (空)
// 最终 Token 字符串:
eyJhbGciOiJub25lIn0.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwicm9sZSI6ImFkbWluIiwiaWF0IjoxNTE2MjM5MDIyfQ.
3.3 密钥泄露
密钥是 JWT 安全体系的基石。一旦密钥泄露,攻击者便获得了与合法服务端同等的签名能力,可以伪造任意身份、权限的 Token。常见的泄露途径包括:
- 硬编码到源代码:密钥直接写在代码中,随版本控制库(如 Git)泄露。
- 配置文件泄露:密钥存储在未加密的配置文件中,被错误地推送到公共仓库。
- 日志输出:调试日志或错误堆栈中打印了密钥信息。
- 第三方依赖:密钥通过不安全的渠道传递给 CI/CD 或微服务。
3.4 算法混淆攻击
算法混淆攻击(Algorithm Confusion Attack)是 JWT 实现中最隐蔽的漏洞之一。当服务端使用 RSA 等非对称算法验证 Token 时,攻击者可以获取公钥,然后将头部算法改为 HMAC(如 HS256),并使用公钥作为 HMAC 密钥对 Token 进行签名。若服务端未校验算法类型与密钥的匹配关系,将使用公钥作为 HMAC 密钥进行验证,从而通过校验。
// 攻击步骤:
// 1. 获取服务端公钥(通常通过 /.well-known/jwks.json 端点)
// 2. 构造 JWT 头部:{"alg":"HS256"}
// 3. 使用公钥字符串作为 HMAC 密钥对载荷进行签名
// 4. 服务端使用公钥作为 HMAC 密钥验证签名,通过校验
// 防御:服务端必须明确指定期望的算法,并拒绝算法类型与密钥类型不匹配的 Token
alg 字段是否在允许列表中。切勿依赖 JWT 库的自动算法检测功能。
3.5 重放攻击
即使 JWT 签名完整且算法正确,攻击者仍可通过网络嗅探或中间人攻击截获合法 Token,并在有效期内重复使用。重放攻击的典型场景包括:用户登录后 Token 被截获,攻击者利用该 Token 执行敏感操作(如转账、修改密码)。
防御重放攻击的常用策略包括:
- 短有效期(exp):将 Token 的过期时间设置为较短窗口(如 15 分钟),降低重放窗口。
- 一次性 Token(jti):在 JWT 载荷中包含唯一标识符
jti,服务端维护已使用jti的黑名单。 - 时间戳校验(iat/nbf):结合
iat(签发时间)和nbf(生效时间)进行时间窗口校验。 - 请求绑定:将 Token 与特定请求参数(如 IP、User-Agent、nonce)绑定,增加重放难度。
3.6 攻击流程与防御闭环
下图展示了四种攻击向量的攻击路径以及对应的防御闭环节点,帮助理解从攻击到防御的完整链路。
3.7 综合防御清单
针对上述四种攻击,以下清单总结了每个环节必须落实的防御措施:
| 攻击类型 | 防御措施 | 实现优先级 |
|---|---|---|
| 无签名攻击 | 验证时强制要求签名存在,拒绝 alg: none;使用白名单算法列表 |
P0(立即修复) |
| 密钥泄露 | 使用密钥管理服务(KMS/Vault);禁止硬编码;定期轮换;最小权限原则 | P0(立即修复) |
| 算法混淆攻击 | 验证时校验算法类型与密钥类型匹配;显式指定算法而非自动检测 | P0(立即修复) |
| 重放攻击 | 短过期时间(exp);jti 唯一标识 + 已使用列表;请求绑定(IP/User-Agent) | P1(高优先级) |