GHSA-49m4-vp58-wgc9 MCP-for-Stata: Stata Command Injection via Unsanitized `package` in `ado_package_install`
Stata Command Injection via Unsanitized `package` in `ado_package_install`SummaryThe `ado_package_install` MCP tool in `stata-mcp` concatenates user-controlled input directly into a Stata command string without any validation or sanitization. An attacker who can invoke the MCP tool or the equivalent Python API can embed newline characters in the `package` argument to inject arbitrary Stata commands. Because Stata supports a `shell` escape command, this leads to full OS-level arbitrary command execution (RCE) under the account running the Stata-MCP server. The tool is registered in the default `all` profile, so no non-default configuration is required. Base CVSS score is **8.4 (High)**.DetailsThe vulnerability originates in `SSC_Install.install()`:The `package` parameter is interpolated into an f-string with no allowlist check, newline rejection, or quoting. The resulting command string is forwarded to the Stata interpreter verbatim:`pexpect.sendline()` writes the full multi-line string to the Stata REPL, which executes each line as a separate Stata command. Because Stata's `shell` (and `!`) commands execute an OS shell command, a newline-delimited payload results in OS command execution.The full source-to-sink data flow is:**Exposure** — `src/stata_mcp/mcp_servers.py:626-632`: `_TOOL_REGISTRY` registers `ado_package_install` in the `all` profile.**Default activation** — `src/stata_mcp/cli/_handlers.py:295-300`: when no `--core`/`--all` flag is given the profile defaults to `all`, so the tool is always enabled.**Propagation** — `src/stata_mcp/mcp_servers.py:308-349`: the MCP argument `package` is passed to `installer(...).install(*args)` without validation.**Sink construction** — `src/stata_mcp/stata/builtin_tools/ado_install/ssc_install.py:15`: `package` is interpolated into `install_command`.**Delivery** — `src/stata_mcp/stata/stata_controller/controller.py:99`: `self.child.sendline(command)` sends the attacker-influenced string to Stata.A guard/blacklist (`src/stata_mcp/guard/blacklist.py:41-60`) registers `shell`, `!`, `winexec`, `unixcmd`, and similar strings as dangerous commands, but the `GuardValidator` that enforces this list is invoked **only** on the `stata_do` path and is not called anywhere in the ado-install path, making the guard entirely ineffective against this attack.PoC**Prerequisites**Unix-like host with a configured Stata CLI, **or** use the provided Docker image which replaces the Stata binary with a minimal Python stub (`fake_stata.py`) that honours the `shell` command.**Container-based reproduction (no Stata license required)****Direct Python trigger (unmodified source)**The payload `"outreg2\nshell touch /tmp/stata_mcp_ado_poc\n//"` is expanded by the f-string at `ssc_install.py:15` into:Stata executes the second line as an OS shell command. The trailing `//` comment neutralises the `, replace` suffix so Stata does not raise a syntax error.**MCP JSON-RPC trigger****Expected output**Phase 2 dynamic reproduction confirmed the marker file `/tmp/stata_mcp_ado_poc` was created inside the Docker container, and `install()` returned a string containing the injected command:ImpactThis is a **Code/Command Injection (RCE)** vulnerability. Any principal who can call the `ado_package_install` MCP tool or the equivalent Python API — including an AI model or agent connected to the MCP server, a local script, or a remote HTTP client if the HTTP transport is exposed — can execute arbitrary OS commands with the privileges of the user running the Stata-MCP server.Because the tool is registered in the default `all` profile and `all` is the default active profile, **no misconfiguration by the victim is required**. All users of `stata-mcp` on the affected version who run `stata-mcp server` are impacted.Concrete consequences include: exfiltration of credentials and data accessible to the process, persistence via cron/startup entries, lateral movement within the local network, and complete compromise of the host user account.Reproduction artifacts`Dockerfile``poc.py`
CVSS v3.1 score: 8.4