
Documenta la CVE-2026-52618 con un PoC per l'iniezione di comandi del sistema operativo in @webfer/mcp-ansible-drupal tramite le extraVars di executeDeployment, oltre a indicazioni per il rilevamento e le mitigazioni.
executeDeploymentspawn(cmd[0], cmd.slice(1), { shell: true }) ricompone un array di argomenti in un'unica stringa /bin/sh -c senza escaping, quindi un metacarattere di shell in un valore extraVars fornito al tool MCP executeDeployment viene eseguito sull'host che esegue il server.
| CVE | CVE-2026-52618 |
| CWE | CWE-78 (Improper Neutralization of Special Elements used in an OS Command) |
| Pacchetto | @webfer/mcp-ansible-drupal (npm) |
| Affected | 2.0.0 |
| Fixed in | 2.0.3 (published 2026-06-01) |
| CVSS v3.1 | AV:L/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H = 8.4 High (stdio transport). AV:N → 9.8 Critical if the server is wrapped in a network transport. |
| Reported by | s1ko (github.com/s1ko, [email protected]) |
| CVE assigned | 2026-07-13, MITRE CNA-LR |
Questo problema è risolto. Aggiornare alla versione 2.0.3 o successiva.
Gli argomenti dei tool MCP sono influenzati dall'attaccante. Sono prodotti da un LLM a partire dal contenuto che l'agente elabora — documenti, pagine web, output di tool — quindi l'iniezione indiretta di prompt mette un attaccante in controllo dei valori che un handler di tool riceve. Un handler che passa uno di questi valori a una shell trasforma tale influenza in esecuzione di codice sull'host che esegue il server MCP. È lo stesso modello del caso precedente aws-mcp-server / CVE-2026-5058.
La conseguenza è che "il chiamante è un LLM fidato" non è una mitigazione. Gli argomenti dei tool sono input non attendibile.
src/helpers/runAnsible.ts nella versione 2.0.0 costruiva un array di argomenti e poi lo eseguiva con la shell abilitata:
const proc = spawn(ansibleCmd[0], ansibleCmd.slice(1), { shell: true });
Con shell: true Node non esegue ansibleCmd[0] con gli elementi rimanenti come argv. Unisce l'intero array in un'unica stringa e la passa a /bin/sh -c, senza applicare alcuna quotatura o escaping agli elementi. Qualsiasi elemento che contenga ;, &&, |, backtick o $() esce quindi dal comando previsto.
Il percorso raggiungibile è lo strumento MCP executeDeployment
(src/tools/executeDeployment.ts), che inoltra gli extraVars forniti dal chiamante
nell'array come --extra-vars key=value. Un valore pari a ; touch /tmp/marker ;
produce:
/bin/sh -c "ansible-playbook -i inv.ini play.yml ... --extra-vars deploy_env=; touch /tmp/marker ; echo INJECTED"
Un secondo sink nella stessa versione interpolava projectRoot in
execSync('ansible-vault encrypt ' + vaultPath).
poc/driver.mjs chiama direttamente runAnsible con un valore
extraVars appositamente costruito e verifica la presenza del file marcatore. Non è
necessario che ansible-playbook sia installato — il comando iniettato viene eseguito nella stessa stringa
/bin/sh -c indipendentemente dal fatto che il binario iniziale venga risolto.
npm pack @webfer/[email protected] && tar xf webfer-mcp-ansible-drupal-2.0.0.tgz
node poc/driver.mjs
Atteso su una versione interessata:
{"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"}
Convalidato il 2026-06-01 in un container isolato e riconvalidato il 2026-06-13 con
un marcatore touch benigno. Eseguilo solo contro infrastrutture che sei autorizzato
a testare.
--extra-vars che raggiunge ansible-playbook e che contiene ;, &&,
||, |, un backtick o $(. I valori legittimi delle variabili Ansible essenzialmente
non lo fanno mai.sh -c la cui riga di comando contiene ansible-playbook e un
secondo comando dopo un separatore — un segnale a livello di albero dei processi (auditd, eBPF,
Falco, EDR) che non dipende dal logging dell'applicazione.ansible-playbook, git e
ansible-vault sono attesi; una shell, un interprete o un client di rete non lo sono.executeDeployment contengono
metacaratteri della shell. Registra gli argomenti degli strumenti — la maggior parte dei deployment MCP
non lo fa, ed è l'unico punto in cui il valore iniettato è visibile in termini applicativi.MITRE ATT&CK T1059.004 Command and Scripting Interpreter: Unix Shell.
Aggiorna a @webfer/mcp-ansible-drupal 2.0.3 o successivo. Il codice sorgente attuale
chiama spawn(ansibleCmd[0], ansibleCmd.slice(1), { … }) senza l'opzione shell,
quindi l'array viene passato come argv e i metacaratteri perdono il loro significato.
La regola generale per i gestori degli strumenti MCP, e ciò che la correzione applica qui:
shell: true quando è già disponibile un array di argomenti. La
forma ad array esiste proprio per evitare la shell.execFile/spawn con un vettore di argomenti esplicito.z.string() di Zod dimostra che il valore è una
stringa e nulla su ciò che contiene. Usa una allowlist dove l'insieme dei valori è
noto; rifiuta i metacaratteri della shell dove non lo è.NIST SP 800-53r5 SI-10; OWASP ASVS v4 §5.3.8; mitigazioni CWE-78 M1 e M2.
| Data | Evento |
|---|---|
| 2026-06-01 | Vulnerabilità convalidata dinamicamente contro la 2.0.0 |
| 2026-06-01 | 2.0.3 pubblicata su npm con shell: true rimosso |
| 2026-06-13 | Riconvalidata su un secondo host |
| 2026-07-13 | MITRE CNA-LR assegna CVE-2026-52618, s1ko accreditato come scopritore |
| 2026-08-22 | Pubblicazione di questo write-up |
aws-mcp-server)Avvisi complementari dalla stessa sessione di ricerca: CVE-2026-52616, CVE-2026-52617.
MIT — vedi LICENSE.