3. JWT 安全风险:无签名攻击、算法混淆攻击、密钥泄露、Payload 敏感信息泄露

JWT(JSON Web Token)作为无状态认证的主流方案,其安全性高度依赖于实现细节。在实际生产环境中,开发者常因对 JWT 规范理解不深或配置不当,引入严重的安全漏洞。本章聚焦四种高频高危风险:无签名攻击、算法混淆攻击、密钥泄露以及Payload 敏感信息泄露,并结合压测场景分析其危害。

⚠️ 核心认知:JWT 的安全性并非由算法本身保证,而是由密钥管理与服务端校验逻辑共同决定。任何一方的疏忽都可能导致整个认证体系被攻破。

3.1 无签名攻击(None Signature Attack)

JWT 规范允许使用 "alg": "none" 表示无签名。当服务端未严格校验算法字段时,攻击者可构造一个不含签名的 Token,绕过身份验证。

攻击原理

  • 攻击者将 JWT Header 中的 alg 字段改为 "none"。
  • 移除 Signature 部分,仅保留 Header.Payload.(注意末尾的点号)。
  • 服务端若直接使用 jwt.decode() 而非 jwt.verify(),或未对 "none" 算法做白名单过滤,则会接受该 Token。

压测场景下的危害

在压测中,攻击者可以批量生成大量无签名 Token,对服务端进行无密钥验证的请求轰炸。由于无需计算签名,攻击者可极快地构造请求,导致认证层被绕过,后端资源直接暴露。

📌 防御要点:服务端必须显式禁用 "none" 算法,并在 JWT 库中配置允许的算法白名单(如仅允许 HS256 或 RS256)。

3.2 算法混淆攻击(Algorithm Confusion Attack)

当服务端支持多种算法(如同时支持 HS256 和 RS256)时,攻击者可利用公钥与密钥的混淆来伪造 Token。

攻击流程

  1. 获取公钥:攻击者通过公开接口或泄露信息获取服务端的 RSA 公钥。
  2. 构造 Token:将 Header 中的 alg 改为 HS256,Payload 任意篡改。
  3. 使用公钥签名:攻击者将公钥字符串作为 HMAC 的密钥,对 Token 进行签名。
  4. 服务端误判:服务端收到 Token 后,根据 Header 中的 HS256 算法,使用公钥(被当作 HMAC 密钥)进行验签,由于公钥是公开的,验签通过。
💡 压测关联:在压测中,算法混淆攻击可导致服务端验签逻辑产生大量异常或误判,影响压测结果的真实性。同时,攻击者可通过此漏洞伪造任意用户身份,对系统进行定向压测攻击。

算法混淆攻击对比表

对比维度 对称算法(HS256) 非对称算法(RS256)
密钥类型 单一密钥(Secret) 公钥 + 私钥对
签名方 服务端(持有密钥) 服务端(持有私钥)
验签方 服务端(持有密钥) 任何持有公钥的客户端或服务端
混淆风险 低(密钥不公开) 高(公钥公开,可被用作 HMAC 密钥)
防御策略 固定算法白名单 强制校验算法类型,拒绝非对称算法使用对称验签

3.3 密钥泄露(Secret Key Leakage)

密钥是 JWT 安全的核心。一旦密钥泄露,攻击者可以签发任意有效 Token,完全控制认证系统。

常见泄露途径

  • 硬编码在代码仓库:密钥直接写在配置文件或代码中,随版本控制泄露。
  • 日志输出:调试日志中打印了密钥或 Token 的签名过程。
  • 环境变量管理不当:密钥通过不安全的环境变量传递,或被容器镜像打包。
  • 弱密钥:使用简单字符串(如 "secret"、"123456")作为密钥,可被暴力破解。

压测中的密钥泄露影响

在压测过程中,若密钥被泄露,攻击者可以生成大量合法 Token,对系统进行持续压测,导致服务端无法区分正常请求与恶意请求,压测数据完全失效。同时,攻击者可以模拟高权限用户,触发系统瓶颈或破坏数据。

⚠️ 密钥管理最佳实践:
  • 使用密钥管理服务(KMS)或 Vault 存储密钥。
  • 定期轮换密钥,并支持多密钥并行验证。
  • 密钥长度至少 256 位(HS256)或 2048 位(RS256)。
  • 禁止在日志、错误信息、响应体中输出密钥或 Token 签名过程。

3.4 Payload 敏感信息泄露

JWT 的 Payload 仅经过 Base64 编码,并非加密。任何持有 Token 的人都可以解码读取 Payload 内容。

常见泄露信息

信息类型 示例 风险等级
用户标识 "sub": "user_12345" 中
角色权限 "role": "admin" 高
个人隐私 "email": "user@example.com" 高
内部结构 "department": "finance" 中
会话标识 "session_id": "abc123" 高

压测场景下的泄露风险

在压测中,Token 可能被记录在压测工具的日志、网络抓包文件或服务端访问日志中。若 Payload 包含敏感信息,这些日志文件一旦泄露,将导致大规模数据泄露。此外,压测过程中生成的 Token 若未及时清理,也可能被后续攻击者利用。

💡 防御建议:
  • 不要在 Payload 中存储密码、身份证号、银行卡号等绝对敏感信息。
  • 使用 JWE(JSON Web Encryption)对 Payload 进行加密,或使用额外的加密层。
  • 压测环境中使用脱敏数据,避免使用真实用户信息。
  • 压测结束后立即吊销或销毁所有生成的 Token。

3.5 四种风险对比总结

风险类型 攻击难度 危害等级 压测影响 核心防御
无签名攻击 低 高 认证绕过,请求量激增 禁用 "none" 算法
算法混淆攻击 中 高 身份伪造,压测数据失真 算法白名单 + 类型校验
密钥泄露 低(一旦泄露) 极高 完全控制认证,压测失效 密钥管理 + 轮换
Payload 敏感信息泄露 低 中-高 数据泄露,合规风险 加密 + 最小化数据

3.6 JWT 安全风险攻击链路图

下图展示了四种安全风险在 JWT 生命周期中的攻击入口与影响链路,帮助理解各风险之间的关联与叠加效应。

JWT 安全风险攻击链路图 JWT Token 无签名攻击 算法混淆攻击 密钥泄露 Payload 信息泄露 认证绕过 身份伪造 完全控制认证 数据泄露 压测影响:认证失效 / 数据失真 / 请求量异常 / 日志泄露 防御策略:算法白名单 + 密钥管理 + Payload 加密 + 最小化数据 + 日志脱敏

3.7 压测诊断中的安全验证要点

在进行 JWT 相关压测时,除了关注性能指标,还应将安全验证纳入诊断流程:

  • 算法白名单测试:在压测脚本中尝试使用 "alg": "none" 或算法混淆 Token,验证服务端是否拒绝。
  • 密钥强度验证:使用弱密钥(如 "secret")生成 Token 进行压测,观察是否被服务端识别并拒绝。
  • Payload 泄露检查:在压测日志中检查是否记录了 Token 的 Payload 内容,确保日志脱敏策略生效。
  • Token 生命周期管理:压测结束后,验证 Token 是否被及时吊销,避免残留 Token 被利用。
📌 压测安全诊断清单:
  1. 确认服务端 JWT 库版本已修复已知漏洞。
  2. 验证算法白名单配置是否生效。
  3. 检查密钥存储方式是否符合安全规范。
  4. 审查 Payload 字段,确保无敏感信息。
  5. 在压测报告中增加安全风险项,记录测试结果。