JSON Web Token (JWT) 安全详解
0x00 JWT 简介
JSON Web Token (JWT) 是一种紧凑的、URL安全的表示方式,用于在双方之间传输声明。JWT 中的声明被编码为 JSON 对象,用作 JSON Web Signature (JWS) 结构的有效载荷或 JSON Web Encryption (JWE) 结构的明文。
JWT 由三部分组成:
- Header (头部)
- Payload (有效载荷)
- Signature (签名)
这三个部分使用 BASE64URL 算法编码(与 BASE64 相似,但 + 替换为 -,/ 替换为 _,且去掉 = 填充)。
示例 JWT 结构:
eyJhbGciOiJIUzI1NiJ9.eyJpc3MiOiIxNjYwNDYiLCJleHAiOjE1NzI4Mzk4NTZ9.aAwuJZBuG2zKBJ04QQ36FvLP-9PesiO30j9VCDDgKR0
解码后:
// header
{
"alg": "HS256"
}
// payload
{
"iss": "166046",
"exp": 1572839856
}
// VERIFY SIGNATURE
HMACSHA256(
base64UrlEncode(header)
base64UrlEncode(payload),
111
)
0x01 JWT 的安全问题
1. 缺乏机密性
JWT 的有效载荷可以轻松解码,如果需要保密数据,应使用 JWE (JSON Web Encryption)。
2. 潜在授权绕过
攻击者可能修改有效载荷并绕过授权检查。虽然签名机制可以防止篡改,但实现不当会导致漏洞。
0x02 JWT 攻击方法
攻击方法一:修改签名算法
攻击步骤:
- 获取一个已签名的 JWT
- 修改标头为
{"alg":"none"} - 发送给服务器(可带或不带签名)
漏洞原因:JWT 规范中 "none" 算法是合规的,但许多库错误地接受了这种无签名的令牌。
相关漏洞:
攻击方法二:删除签名
攻击步骤:
- 获取一个使用 HS256/HS512 等算法签名的 JWT
- 删除整个签名部分
- 发送给服务器
漏洞原因:某些库在签名缺失时仍会解码并验证令牌。
案例:
攻击方法三:插入错误信息
攻击步骤:
- 修改有效载荷
- 服务器返回错误信息可能包含敏感信息(如预期签名)
漏洞原因:服务器配置不当,在错误信息中泄露敏感数据。
案例:
攻击方法四:破解 HMAC 密钥
攻击步骤:
- 获取一个 JWT 令牌
- 使用暴力破解/字典攻击破解 HMAC 密钥
工具:
hashcat -m 16500 jwt.txt -a 3 -w 3 ?a?a?a?a?a?a- c-jwt-cracker
安全要求:根据 RFC,HMAC 密钥长度应至少与哈希输出相同(HS256 需要 256 位密钥)。
攻击方法五:利用签名方法混淆
攻击步骤(针对 RSA 算法):
- 获取服务器的公钥
- 修改标头为
HS256但使用 RSA 公钥作为 HMAC 密钥 - 服务器使用公钥验证 HMAC 签名
漏洞原因:服务器未强制使用特定签名算法,允许攻击者指定算法。
案例:
攻击方法六:信任攻击者密钥
攻击步骤:
- 攻击者在令牌中嵌入自己的公钥
- 服务器使用攻击者提供的公钥验证签名
案例:
攻击方法七:恢复私钥
针对 JWE 加密的漏洞:
攻击方法八:上下文相同令牌
漏洞原因:多个服务器使用相同签名密钥,一旦泄露可生成任意有效令牌。
解决方案:使用 iss (签发者) 和 aud (受众) 声明限制令牌使用范围。
攻击方法九:重放 JWT
攻击步骤:
- 获取一个有效令牌(如用于 DELETE 操作)
- 在令牌过期后重新使用
解决方案:使用 jti (JWT ID) 和 exp (过期时间) 声明,并确保正确实现。
案例:
攻击方法十:定时攻击签名
攻击原理:通过测量签名验证响应时间差异,逐步破解签名。
研究显示:在实验室条件下,每秒 55,000 请求可在 22 小时内破解签名。
防御措施:使用恒定时间比较算法验证签名。
0x03 JWT 安全最佳实践
设计与实现
- 明确需求:确定需要 JWS 还是 JWE,选择合适的算法
- 强制使用特定签名算法,不允许客户端指定
- 区分
verify()和decode()功能 - 关闭调试模式,防止信息泄露
密钥管理
- 使用足够强度的密钥(HS256 至少 256 位)
- 密钥不在代码中硬编码,安全存储
- 制定密钥泄露应急方案
- 生产与测试环境使用不同密钥
签名验证
- 拒绝
"none"算法 - 拒绝缺失签名的令牌
- 检查 JWE 使用的加密算法是否安全
- 使用恒定时间算法比较签名
令牌管理
- 不在 URL 中传递令牌(防止日志记录)
- 设置合理的短有效期(
exp声明) - 实现令牌吊销机制
- 使用
iss和aud声明限制使用范围 - 检查
jti唯一性防止重放
库安全
- 定期检查使用的 JWT 库漏洞
- 及时更新到安全版本
- 监控新发现的漏洞
0x04 JWT 替代方案
PASETO (Platform-Agnostic Security Tokens)
PASETO 旨在解决 JWT 的设计缺陷,提供更安全的替代方案。
特点:
- 更简单的设计
- 强制使用安全算法
- 无
"none"算法等危险选项
资源: