JWT安全漏洞与防护(实战进阶篇)
字数 1239 2025-11-09 21:07:05
JWT安全漏洞与防护(实战进阶篇)
1. 知识点描述
JWT(JSON Web Token)作为现代分布式系统的核心认证机制,其安全性直接影响整个应用架构。本专题深入探讨JWT在实战中的三类高危漏洞:密钥混淆攻击(Key Confusion)、JKU/JWK头参数滥用、逻辑性时效控制缺陷。这些漏洞源于开发者在JWT实现过程中的特定配置错误或逻辑盲点,可导致身份伪造、权限提升等严重后果。
2. 漏洞原理与攻击链分析
2.1 密钥混淆攻击(CVE-2015-9235)
- 核心问题:服务端验证签名时未严格绑定签名算法。攻击者将头部中的算法改为
none(部分库支持)或从非对称算法(如RS256)改为对称算法(如HS256)。 - 攻击步骤:
- 捕获合法JWT令牌,头部原为
{"alg":"RS256","typ":"JWT"} - 修改头部为
{"alg":"HS256","typ":"JWT"},使用服务端的RSA公钥(本应仅用于验证)作为HS256的密钥 - 用公钥重新生成签名,服务端误用公钥进行HS256验证时会匹配
- 捕获合法JWT令牌,头部原为
- 关键条件:服务端代码动态接受头部算法参数,且未校验算法一致性
2.2 JKU/JWK参数劫持
- 漏洞场景:JWT头部含
jku(JWK Set URL)或jwk(嵌入式公钥)参数时,服务端若未限制外部密钥源,可能加载攻击者控制的密钥 - 攻击链还原:
# 恶意JWT头部 { "alg": "RS256", "jku": "https://attacker.com/jwks.json", "kid": "malicious-key" }- 攻击者在自有域名托管伪造的JWK Set(
{"keys":[{"kid":"malicious-key","n":"恶意模数","e":"AQAB"}]}) - 服务端信任该jku地址,用攻击者公钥验证签名
- 攻击者用对应私钥签名令牌实现身份伪造
- 攻击者在自有域名托管伪造的JWK Set(
2.3 逻辑性时效控制缺陷
- 典型误区:仅依赖JWTpayload内的
exp(过期时间)字段,但未在服务端维护令牌状态 - 绕过手法:
- 时间篡改:修改服务器时间绕过exp校验(需结合其他漏洞)
- 注销失效:用户退出后令牌仍有效,形成"僵尸令牌"
- 刷新令牌滥用:刷新令牌无访问范围限制,可生成永久有效令牌
3. 防护方案设计模式
3.1 算法验证固化
# 错误示例:动态接受算法
decoded = jwt.decode(token, key='public_key', algorithms=['RS256','HS256'])
# 正确方案:固定预期算法
decoded = jwt.decode(token, key='rsa_public_key', algorithms=['RS256']) # 明确拒绝算法参数
3.2 密钥源白名单化
- 禁用外部JKU/JWK参数,仅允许预置密钥
- 若需使用JKU,应校验域名是否在许可列表(如内部认证服务域名)
allowed_jku_domains = ['auth.company.com']
jku_url = decoded_header.get('jku')
if jku_url and urlparse(jku_url).netloc not in allowed_jku_domains:
raise InvalidTokenError("Untrusted JWK source")
3.3 状态化令牌管理
- 短期令牌+刷新机制:access_token有效期≤15分钟,refresh_token绑定设备指纹
- 令牌黑名单:用户登出时记录令牌ID至Redis(键过期时间略大于令牌有效期)
-- 令牌元数据表
CREATE TABLE revoked_tokens (
jti UUID PRIMARY KEY, -- 令牌唯一ID
revoked_at TIMESTAMP DEFAULT NOW(),
expire_at TIMESTAMP -- 清理时间点
);
4. 企业级安全实践
4.1 密钥轮转策略
- 支持多版本密钥(kid标识),逐步淘汰旧密钥
- 紧急场景下可触发全局令牌撤销(如检测大规模泄漏)
4.2 深度防御检测
- 监控异常算法变更(如RS256→HS256的请求比例突增)
- 实时阻断JKU指向外部域名的令牌使用
通过结合算法固化、密钥管控、状态验证三层防护,可构建生产级安全的JWT实现方案。