三种针对JSON Web Tokens的新攻击方式
字数 1267 2025-08-19 12:42:40
JSON Web Tokens (JWT) 新型攻击方式研究
1. JWT 基础回顾
JSON Web Tokens (JWT) 是一种开放标准 (RFC 7519),用于在各方之间安全地传输信息作为 JSON 对象。JWT 通常由三部分组成:
- Header:包含令牌类型和签名算法
- Payload:包含声明(claims)
- Signature:用于验证令牌的完整性
典型格式:header.payload.signature
2. 三种新型JWT攻击方式
2.1 基于算法混淆的攻击 (Algorithm Confusion Attack)
原理
- 当服务器使用非对称算法(如RS256)验证JWT,但允许客户端指定算法时
- 攻击者可将算法改为对称算法(如HS256),并使用公钥作为密钥
攻击步骤
- 获取服务器的公钥
- 修改JWT头部,将算法改为HS256
- 使用公钥作为HS256的密钥重新签名
- 发送修改后的令牌到服务器
防御措施
- 严格限制可接受的签名算法
- 不依赖客户端提供的算法声明
- 对HS256使用强密钥
2.2 基于密钥注入的攻击 (Key Injection Attack)
原理
- 某些JWT库在验证签名时,会从令牌中提取密钥
- 攻击者可注入自己的公钥/密钥对
攻击步骤
- 生成自己的RSA密钥对
- 在JWT头部添加公钥(如
jwk或x5c参数) - 使用私钥签名令牌
- 服务器验证时会使用攻击者提供的公钥
防御措施
- 禁用从令牌中提取密钥的功能
- 使用固定的密钥列表
- 检查密钥来源是否可信
2.3 基于无效曲线的攻击 (Invalid Curve Attack)
原理
- 针对使用ECDSA算法的JWT
- ECDSA实现中可能未正确验证公钥是否在预期曲线上
- 攻击者可构造特殊公钥使签名验证通过
攻击步骤
- 选择一个小阶子群
- 计算该子群上的离散对数
- 构造无效曲线上的公钥
- 伪造签名使验证通过
防御措施
- 实现完整的公钥验证
- 检查公钥是否在预期曲线上
- 使用标准化的曲线参数
3. 攻击复现与验证
实验环境搭建
- 使用易受攻击的JWT库(如旧版python-jose)
- 配置服务器接受多种算法
- 启用从令牌提取密钥的功能
算法混淆攻击复现
import jwt
from jwt.algorithms import RSAAlgorithm
# 获取服务器公钥
public_key = """-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu1SU1LfVLPHCozMxH2Mo
...
-----END PUBLIC KEY-----"""
# 构造恶意令牌
malicious_token = jwt.encode(
{"user": "admin"},
key=public_key,
algorithm="HS256"
)
# 发送到易受攻击的服务器
密钥注入攻击复现
import jwt
from cryptography.hazmat.primitives.asymmetric import rsa
# 生成攻击者密钥对
private_key = rsa.generate_private_key(public_exponent=65537, key_size=2048)
public_key = private_key.public_key()
# 构造恶意令牌
malicious_token = jwt.encode(
{"user": "admin"},
key=private_key,
algorithm="RS256",
headers={"jwk": public_key}
)
# 发送到易受攻击的服务器
4. 防御建议
通用防御策略
- 算法白名单:只允许特定的签名算法
- 密钥管理:
- 不使用客户端提供的密钥
- 固定验证密钥
- 库选择:
- 使用维护良好的JWT库
- 定期更新库版本
- 验证完整性:
- 检查公钥是否在预期曲线上(对ECDSA)
- 验证密钥来源
具体配置示例
-
禁用危险配置:
# 使用PyJWT的安全配置 jwt.decode(token, key='secret', algorithms=['HS256'], options={"verify_aud": False}) -
安全的密钥处理:
# 不信任令牌中的密钥声明 decoded = jwt.decode(token, key=fixed_public_key, algorithms=['RS256'])
5. 总结
本文介绍了三种针对JWT的新型攻击方式,这些攻击利用了JWT实现中的算法混淆、密钥注入和椭圆曲线验证不足等漏洞。防御这些攻击需要开发者深入理解JWT的安全机制,并采取严格的验证策略和密钥管理措施。
关键点总结:
- 永远不要信任客户端提供的算法声明
- 固定验证密钥,不从令牌中提取密钥
- 对ECDSA实现完整的曲线验证
- 使用最新版本的JWT库并保持更新
- 实施最小权限原则,限制JWT的权限范围