Sploitus

Exploit for CVE-2026-52618 CVE-2026-52616 CVE-2026-52617 CVE-2026-52618

githubexploit Β· 2026-08-22

Exploit Code

README143 lines
## https://sploitus.com/exploit?id=5C5A7971-4F01-5F90-A72C-A9BB9373CCF7
# CVE-2026-52618 β€” @webfer/mcp-ansible-drupal: OS command injection via `executeDeployment` extra vars

`spawn(cmd[0], cmd.slice(1), { shell: true })` re-joins an argument array into a
single `/bin/sh -c` string without escaping, so a shell metacharacter in an
`extraVars` value supplied to the `executeDeployment` MCP tool executes on the
host running the server.

| | |
|---|---|
| CVE | CVE-2026-52618 |
| CWE | CWE-78 (Improper Neutralization of Special Elements used in an OS Command) |
| Package | [`@webfer/mcp-ansible-drupal`](https://www.npmjs.com/package/@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` = **7.8 High** (stdio transport). `AV:N` β†’ 9.8 Critical if the server is wrapped in a network transport. |
| Reported by | s1ko ([github.com/s1ko](https://github.com/s1ko), `s1ko@riseup.net`) |
| CVE assigned | 2026-07-13, MITRE CNA-LR |

**This issue is fixed. Upgrade to 2.0.3 or later.**

## Threat model

MCP tool arguments are attacker-influenced. They are produced by an LLM from
the content the agent processes β€” documents, web pages, tool output β€” so
indirect prompt injection puts an attacker in control of the values a tool
handler receives. A handler that feeds any of those values into a shell turns
that influence into code execution on the host running the MCP server. This is
the same model as the precedent case `aws-mcp-server` / CVE-2026-5058.

The consequence is that "the caller is a trusted LLM" is not a mitigation.
Tool arguments are untrusted input.

## Execution

`src/helpers/runAnsible.ts` in 2.0.0 built an argument array and then ran it
with the shell enabled:

```js
const proc = spawn(ansibleCmd[0], ansibleCmd.slice(1), { shell: true });
```

With `shell: true` Node does not execute `ansibleCmd[0]` with the remaining
elements as `argv`. It joins the whole array into one string and hands it to
`/bin/sh -c`, with no quoting or escaping applied to the elements. Any element
carrying `;`, `&&`, `|`, backticks or `$()` therefore breaks out of the intended
command.

The reachable path is the `executeDeployment` MCP tool
(`src/tools/executeDeployment.ts`), which forwards caller-supplied `extraVars`
into the array as `--extra-vars key=value`. A value of `; touch /tmp/marker ;`
yields:

```
/bin/sh -c "ansible-playbook -i inv.ini play.yml ... --extra-vars deploy_env=; touch /tmp/marker ; echo INJECTED"
```

A secondary sink in the same version interpolated `projectRoot` into
`execSync('ansible-vault encrypt ' + vaultPath)`.

### Reproduction

[`poc/driver.mjs`](poc/driver.mjs) calls `runAnsible` directly with a crafted
`extraVars` value and checks for the marker file. `ansible-playbook` does not
need to be installed β€” the injected command runs in the same `/bin/sh -c`
string regardless of whether the leading binary resolves.

```
npm pack @webfer/mcp-ansible-drupal@2.0.0 && tar xf webfer-mcp-ansible-drupal-2.0.0.tgz
node poc/driver.mjs
```

Expected on an affected version:

```json
{"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"}
```

Validated 2026-06-01 in an isolated container and re-validated 2026-06-13 with
a benign `touch` marker. Run it only against infrastructure you are authorized
to test.

## Detection

- Any `--extra-vars` value reaching `ansible-playbook` that contains `;`, `&&`,
  `||`, `|`, a backtick or `$(`. Legitimate Ansible variable values essentially
  never do.
- A `sh -c` process whose command line contains `ansible-playbook` **and** a
  second command after a separator β€” a process-tree signal (auditd, eBPF,
  Falco, EDR) that does not depend on application logging.
- Unexpected children of the MCP server process. `ansible-playbook`, `git` and
  `ansible-vault` are expected; a shell, an interpreter or a network client is
  not.
- MCP tool-call logs where `executeDeployment` arguments contain shell
  metacharacters. Log tool arguments β€” most MCP deployments do not, and it is
  the only place the injected value is visible in application terms.

MITRE ATT&CK [T1059.004 Command and Scripting Interpreter: Unix
Shell](https://attack.mitre.org/techniques/T1059/004/).

## Mitigation

**Upgrade to `@webfer/mcp-ansible-drupal` 2.0.3 or later.** The current source
calls `spawn(ansibleCmd[0], ansibleCmd.slice(1), { … })` with no `shell` option,
so the array is passed as `argv` and metacharacters lose their meaning.

The general rule for MCP tool handlers, and what the fix applies here:

- Never enable `shell: true` when an argument array is already available. The
  array form exists precisely to avoid the shell.
- Never build a command by string interpolation of a tool argument. Use
  `execFile`/`spawn` with an explicit argument vector.
- Validate content, not just type. A Zod `z.string()` proves the value is a
  string and nothing about what is in it. Allowlist where the value set is
  known; reject shell metacharacters where it is not.
- Run the MCP server as an unprivileged user with the narrowest filesystem and
  network reach the tool actually needs.

NIST SP 800-53r5 `SI-10`; OWASP ASVS v4 Β§5.3.8; CWE-78 mitigations M1 and M2.

## Timeline

| Date | Event |
|---|---|
| 2026-06-01 | Vulnerability dynamically validated against 2.0.0 |
| 2026-06-01 | 2.0.3 published to npm with the `shell: true` removed |
| 2026-06-13 | Re-validated on a second host |
| 2026-07-13 | MITRE CNA-LR assigns CVE-2026-52618, s1ko credited as discoverer |
| 2026-08-22 | This write-up published |

## References

- npm package β€” https://www.npmjs.com/package/@webfer/mcp-ansible-drupal
- Repository β€” https://github.com/webfer/MCP-Ansible-Drupal
- Precedent for the MCP threat model β€” CVE-2026-5058 (`aws-mcp-server`)

Companion advisories from the same research pass:
[CVE-2026-52616](https://github.com/s1ko/CVE-2026-52616),
[CVE-2026-52617](https://github.com/s1ko/CVE-2026-52617).

## License

MIT β€” see [LICENSE](LICENSE).