
Документирует CVE-2026-52618 с PoC для инъекции команд ОС в @webfer/mcp-ansible-drupal через extraVars в executeDeployment, а также рекомендации по обнаружению и меры по смягчению последствий.
executeDeploymentspawn(cmd[0], cmd.slice(1), { shell: true }) повторно объединяет массив аргументов в
одну строку /bin/sh -c без экранирования, поэтому метасимвол оболочки в
значении extraVars, переданном инструменту MCP executeDeployment, выполняется на
хосте, где запущен сервер.
| CVE | CVE-2026-52618 |
| CWE | CWE-78 (Ненадлежащая нейтрализация специальных элементов, используемых в команде ОС) |
| Пакет | @webfer/mcp-ansible-drupal (npm) |
| Затронуто | 2.0.0 |
| Исправлено в | 2.0.3 (опубликовано 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). AV:N → 9.8 Critical, если сервер обёрнут в сетевой транспорт. |
| Сообщил | s1ko (github.com/s1ko, [email protected]) |
| CVE присвоен | 2026-07-13, MITRE CNA-LR |
Эта проблема исправлена. Обновитесь до 2.0.3 или более поздней версии.
Аргументы инструментов MCP находятся под влиянием атакующего. Они формируются LLM из
содержимого, которое обрабатывает агент — документов, веб-страниц, вывода инструментов — поэтому
косвенная инъекция промпта даёт атакующему контроль над значениями, которые получает
обработчик инструмента. Обработчик, передающий любое из этих значений в оболочку, превращает
это влияние в выполнение кода на хосте, где запущен сервер MCP. Это
та же модель, что и в прецедентном случае aws-mcp-server / CVE-2026-5058.
Следствие: «вызывающий — доверенная LLM» не является мерой защиты. Аргументы инструментов — это недоверенный ввод.
src/helpers/runAnsible.ts в 2.0.0 формировал массив аргументов, а затем запускал его
с включённой оболочкой:
const proc = spawn(ansibleCmd[0], ansibleCmd.slice(1), { shell: true });
При shell: true Node не выполняет ansibleCmd[0] с остальными элементами в качестве argv. Он объединяет весь массив в одну строку и передаёт её в /bin/sh -c, не применяя к элементам никакого экранирования или кавычек. Поэтому любой элемент, содержащий ;, &&, |, обратные кавычки или $(), выходит за пределы предполагаемой команды.
Достижимый путь — это MCP-инструмент executeDeployment (src/tools/executeDeployment.ts), который передаёт предоставленные вызывающей стороной extraVars в массив как --extra-vars key=value. Значение ; touch /tmp/marker ; даёт:
/bin/sh -c "ansible-playbook -i inv.ini play.yml ... --extra-vars deploy_env=; touch /tmp/marker ; echo INJECTED"
Второй сток в той же версии интерполировал projectRoot в
execSync('ansible-vault encrypt ' + vaultPath).
poc/driver.mjs напрямую вызывает runAnsible со специально сформированным
значением extraVars и проверяет наличие файла-маркера. ansible-playbook не
требуется устанавливать — внедрённая команда выполняется в той же строке /bin/sh -c
независимо от того, разрешается ли ведущий бинарный файл.
npm pack @webfer/[email protected] && tar xf webfer-mcp-ansible-drupal-2.0.0.tgz
node poc/driver.mjs
Ожидается на уязвимой версии:
{"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"}
Проверено 2026-06-01 в изолированном контейнере и повторно проверено 2026-06-13 с
безвредным маркером touch. Запускайте только против инфраструктуры, которую вы уполномочены
тестировать.
--extra-vars, попадающее в ansible-playbook, которое содержит ;, &&,
||, |, обратную кавычку или $(. Легитимные значения переменных Ansible практически
никогда их не содержат.sh -c, командная строка которого содержит ansible-playbook и
вторую команду после разделителя — сигнал на уровне дерева процессов (auditd, eBPF,
Falco, EDR), не зависящий от логирования приложения.ansible-playbook, git и
ansible-vault ожидаемы; оболочка, интерпретатор или сетевой клиент — нет.executeDeployment содержат метасимволы
оболочки. Логируйте аргументы инструментов — большинство развёртываний MCP этого не делают, и это
единственное место, где внедрённое значение видно в терминах приложения.MITRE ATT&CK T1059.004 Command and Scripting Interpreter: Unix Shell.
Обновитесь до @webfer/mcp-ansible-drupal 2.0.3 или более поздней версии. Текущий исходный код
вызывает spawn(ansibleCmd[0], ansibleCmd.slice(1), { … }) без опции shell,
поэтому массив передаётся как argv, и метасимволы теряют своё значение.
Общее правило для обработчиков инструментов MCP, и именно его применяет исправление здесь:
shell: true, когда массив аргументов уже доступен. Форма
с массивом существует именно для того, чтобы избежать оболочки.execFile/spawn с явным вектором аргументов.z.string() доказывает, что значение является
строкой, и ничего не говорит о том, что в ней находится. Используйте allowlist там, где набор значений
известен; отклоняйте метасимволы оболочки там, где он неизвестен.NIST SP 800-53r5 SI-10; OWASP ASVS v4 §5.3.8; меры смягчения CWE-78 M1 и M2.
| Дата | Событие |
|---|---|
| 2026-06-01 | Уязвимость динамически подтверждена на версии 2.0.0 |
| 2026-06-01 | Версия 2.0.3 опубликована в npm с удалённым shell: true |
| 2026-06-13 | Повторно подтверждена на втором хосте |
| 2026-07-13 | MITRE CNA-LR присваивает CVE-2026-52618, s1ko указан как обнаруживший |
| 2026-08-22 | Опубликован этот отчёт |
aws-mcp-server)Сопутствующие рекомендации из того же исследовательского прохода: CVE-2026-52616, CVE-2026-52617.
MIT — см. LICENSE.