
Documenta a CVE-2026-52618 com um PoC para injeção de comandos no sistema operacional em @webfer/mcp-ansible-drupal via executeDeployment extraVars, além de orientações de detecção e mitigações.
executeDeployment extra varsspawn(cmd[0], cmd.slice(1), { shell: true }) recombina um array de argumentos em uma
única string /bin/sh -c sem escape, portanto um metacaractere de shell em um
valor extraVars fornecido à ferramenta MCP executeDeployment é executado no
host que executa o servidor.
Este problema foi corrigido. Atualize para 2.0.3 ou posterior.
Os argumentos das ferramentas MCP são influenciados pelo atacante. Eles são produzidos por um LLM a partir de
conteúdo que o agente processa — documentos, páginas da web, saída de ferramentas — portanto,
a injeção indireta de prompt coloca o atacante no controle dos valores que um
manipulador de ferramenta recebe. Um manipulador que alimenta qualquer um desses valores a um shell transforma
essa influência em execução de código no host que executa o servidor MCP. Este é
o mesmo modelo do caso precedente aws-mcp-server / CVE-2026-5058.
A consequência é que "o chamador é um LLM confiável" não é uma mitigação. Os argumentos da ferramenta são entrada não confiável.
src/helpers/runAnsible.ts na versão 2.0.0 construiu um array de argumentos e então o executou
com o shell habilitado:
const proc = spawn(ansibleCmd[0], ansibleCmd.slice(1), { shell: true });
Com shell: true, o Node não executa ansibleCmd[0] com os elementos restantes
como argv. Ele une todo o array em uma única string e a entrega a
/bin/sh -c, sem aplicar aspas ou escape aos elementos. Qualquer elemento
contendo ;, &&, |, crases ou $() portanto escapa do
comando pretendido.
O caminho acessível é a ferramenta MCP executeDeployment
(src/tools/executeDeployment.ts), que encaminha extraVars fornecidos pelo chamador
para o array como --extra-vars key=value. Um valor de ; touch /tmp/marker ;
produz:
/bin/sh -c "ansible-playbook -i inv.ini play.yml ... --extra-vars deploy_env=; touch /tmp/marker ; echo INJECTED"
Um sumidouro secundário na mesma versão interpolou projectRoot em
execSync('ansible-vault encrypt ' + vaultPath).
poc/driver.mjs chama runAnsible diretamente com um
valor extraVars criado e verifica o arquivo marcador. O ansible-playbook não
precisa estar instalado — o comando injetado é executado na mesma /bin/sh -c
string, independentemente de o binário inicial ser resolvido.
npm pack @webfer/[email protected] && tar xf webfer-mcp-ansible-drupal-2.0.0.tgz
node poc/driver.mjs
Esperado em uma versão afetada:
{"target":"@webfer/mcp-ansible-drupal 2.0.0","sink":"runAnsible -> spawn(cmd[0], cmd.slice(1), {shell:true})","vector":"executeDeployment extraVars value","marker":"/tmp/PWNED_ansible","created":true,"verdict":"CONFIRMED - command injection executed"}
Validado em 2026-06-01 em um contêiner isolado e revalidado em 2026-06-13 com
um marcador touch benigno. Execute-o apenas contra infraestrutura que você está autorizado
a testar.
--extra-vars que chegue ao ansible-playbook contendo ;, &&,
||, |, uma crase ou $(. Valores legítimos de variáveis Ansible essencialmente
nunca contêm.sh -c cuja linha de comando contenha ansible-playbook e um
segundo comando após um separador — um sinal de árvore de processos (auditd, eBPF,
Falco, EDR) que não depende do log da aplicação.ansible-playbook, git e
ansible-vault são esperados; um shell, um interpretador ou um cliente de rede não
é.executeDeployment contêm
metacaracteres de shell. Registre os argumentos das ferramentas — a maioria das implantações MCP não faz isso, e é
o único lugar onde o valor injetado é visível em termos de aplicação.MITRE ATT&CK T1059.004 Command and Scripting Interpreter: Unix Shell.
Atualize para @webfer/mcp-ansible-drupal 2.0.3 ou posterior. O código atual
chama spawn(ansibleCmd[0], ansibleCmd.slice(1), { … }) sem a opção shell,
portanto o array é passado como argv e os metacaracteres perdem o significado.
A regra geral para manipuladores de ferramentas MCP, e o que a correção aplica aqui:
shell: true quando um array de argumentos já estiver disponível. O
formato de array existe precisamente para evitar o shell.execFile/spawn com um vetor de argumentos explícito.z.string() prova que o valor é uma
string e nada sobre o que está nela. Use lista de permissões quando o conjunto de valores for
conhecido; rejeite metacaracteres de shell quando não for.NIST SP 800-53r5 SI-10; OWASP ASVS v4 §5.3.8; mitigações CWE-78 M1 e M2.
aws-mcp-server)Avisos complementares da mesma pesquisa: CVE-2026-52616, CVE-2026-52617.
MIT — consulte LICENSE.
| CVE | CVE-2026-52618 |
| CWE | CWE-78 (Improper Neutralization of Special Elements used in an OS Command) |
| Pacote | @webfer/mcp-ansible-drupal (npm) |
| Afetado | 2.0.0 |
| Corrigido em | 2.0.3 (publicado em 2026-06-01) |
| CVSS v3.1 | AV:L/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H = 7.8 Alto (transporte via stdio). AV:N → 9.8 Crítico se o servidor estiver encapsulado em um transporte de rede. |
| Relatado por | s1ko (github.com/s1ko, [email protected]) |
| CVE atribuído | 2026-07-13, MITRE CNA-LR |
| Data |
|---|
| Evento |
|---|
| 2026-06-01 | Vulnerabilidade validada dinamicamente contra 2.0.0 |
| 2026-06-01 | 2.0.3 publicada no npm com o shell: true removido |
| 2026-06-13 | Revalidada em um segundo host |
| 2026-07-13 | MITRE CNA-LR atribui CVE-2026-52618, s1ko creditado como descobridor |
| 2026-08-22 | Este relatório publicado |