3. JWT 安全风险:无签名攻击、算法混淆攻击、密钥泄露、Payload 敏感信息泄露
JWT(JSON Web Token)作为无状态认证的主流方案,其安全性高度依赖于实现细节。在实际生产环境中,开发者常因对 JWT 规范理解不深或配置不当,引入严重的安全漏洞。本章聚焦四种高频高危风险:无签名攻击、算法混淆攻击、密钥泄露以及Payload 敏感信息泄露,并结合压测场景分析其危害。
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。
攻击流程
- 获取公钥:攻击者通过公开接口或泄露信息获取服务端的 RSA 公钥。
- 构造 Token:将 Header 中的
alg改为HS256,Payload 任意篡改。 - 使用公钥签名:攻击者将公钥字符串作为 HMAC 的密钥,对 Token 进行签名。
- 服务端误判:服务端收到 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 生命周期中的攻击入口与影响链路,帮助理解各风险之间的关联与叠加效应。
3.7 压测诊断中的安全验证要点
在进行 JWT 相关压测时,除了关注性能指标,还应将安全验证纳入诊断流程:
- 算法白名单测试:在压测脚本中尝试使用
"alg": "none"或算法混淆 Token,验证服务端是否拒绝。 - 密钥强度验证:使用弱密钥(如
"secret")生成 Token 进行压测,观察是否被服务端识别并拒绝。 - Payload 泄露检查:在压测日志中检查是否记录了 Token 的 Payload 内容,确保日志脱敏策略生效。
- Token 生命周期管理:压测结束后,验证 Token 是否被及时吊销,避免残留 Token 被利用。
- 确认服务端 JWT 库版本已修复已知漏洞。
- 验证算法白名单配置是否生效。
- 检查密钥存储方式是否符合安全规范。
- 审查 Payload 字段,确保无敏感信息。
- 在压测报告中增加安全风险项,记录测试结果。