GHSA-4P62-HQP5-G644

Vulnerability from github – Published: 2026-06-04 21:00 – Updated: 2026-06-04 21:00
VLAI
Summary
MCP-for-Stata: Command injection via log_file_name parameter in Stata command wrapper
Details

Summary

The log_file_name parameter in the stata_do API and CLI is directly interpolated into a Stata command string without sanitization. The security guard (GuardValidator) only scans the do-file content but does not validate this parameter. An attacker can inject arbitrary Stata commands (including shell, python, erase, etc.) by crafting a malicious log_file_name containing quotes, newlines, or Stata command separators.

Details

In src/stata_mcp/stata/stata_do/do.py, both _execute_unix_like and _execute_windows construct a Stata command string using Python f-strings:

commands = f"""
capture log close
{self.generate_log_command(log_file, is_replace)}
...
do "{dofile_path}"
...
"""

The generate_log_command method returns:

log_cmd = f'log using "{log_file.as_posix()}", {replace_clause} {log_type} name({log_type}_log)'

Where log_file is constructed from user-supplied log_name:

def generate_log_file(self, log_name: str, extension='log'):
    return self.log_file_path / f"{log_name}.{extension}"

The log_name parameter comes directly from user input (via MCP tool stata_do or CLI stata-mcp tool do) without any validation. Since the path is embedded inside double quotes in a Stata command string, an attacker can break out of the string context and inject arbitrary commands.

Additionally, generate_log_file does not prevent path traversal via log_name, allowing arbitrary file write outside the intended log directory.

Proof of Concept

When calling stata_do via MCP tool with:

{
  "dofile_path": "test.do",
  "log_file_name": "'; shell echo pwned > /tmp/pwned.txt; '"
}

The generated Stata commands become:

log using "<log_dir>/'; shell echo pwned > /tmp/pwned.txt; '.log", replace text name(text_log)

Stata interprets this as multiple commands, with shell echo pwned > /tmp/pwned.txt; executed as an arbitrary shell command.

Impact

  • Remote Code Execution via shell command injection
  • Arbitrary file write/overwrite via path traversal in log_name
  • Complete bypass of the security guard, as the guard only validates do-file content, not wrapper parameters

Remediation / Fix

  1. Apply strict allowlist validation to log_name (only alphanumeric, underscore, dot, hyphen; max 128 chars)
  2. Resolve and verify the constructed log path remains within the intended log directory
  3. Consider generating safe internal filenames (e.g., UUIDs) instead of accepting user-defined log names for command construction
  4. Apply similar sanitization to dofile_path before embedding it into Stata command strings

References

  • Issue: #74
  • Fix commit: https://github.com/SepineTam/stata-mcp/commit/e6f945941ae0c7cf5e74a428e0b3dc82b396382f
Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "PyPI",
        "name": "stata-mcp"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "1.17.3"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-47708"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-77"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-06-04T21:00:42Z",
    "nvd_published_at": null,
    "severity": "CRITICAL"
  },
  "details": "### Summary\nThe `log_file_name` parameter in the `stata_do` API and CLI is directly interpolated into a Stata command string without sanitization. The security guard (`GuardValidator`) only scans the do-file content but does not validate this parameter. An attacker can inject arbitrary Stata commands (including `shell`, `python`, `erase`, etc.) by crafting a malicious `log_file_name` containing quotes, newlines, or Stata command separators.\n\n### Details\n\nIn `src/stata_mcp/stata/stata_do/do.py`, both `_execute_unix_like` and `_execute_windows` construct a Stata command string using Python f-strings:\n\n```python\ncommands = f\"\"\"\ncapture log close\n{self.generate_log_command(log_file, is_replace)}\n...\ndo \"{dofile_path}\"\n...\n\"\"\"\n```\n\nThe `generate_log_command` method returns:\n\n```python\nlog_cmd = f\u0027log using \"{log_file.as_posix()}\", {replace_clause} {log_type} name({log_type}_log)\u0027\n```\n\nWhere `log_file` is constructed from user-supplied `log_name`:\n\n```python\ndef generate_log_file(self, log_name: str, extension=\u0027log\u0027):\n    return self.log_file_path / f\"{log_name}.{extension}\"\n```\n\nThe `log_name` parameter comes directly from user input (via MCP tool `stata_do` or CLI `stata-mcp tool do`) without any validation. Since the path is embedded inside double quotes in a Stata command string, an attacker can break out of the string context and inject arbitrary commands.\n\nAdditionally, `generate_log_file` does not prevent path traversal via `log_name`, allowing arbitrary file write outside the intended log directory.\n\n### Proof of Concept\n\nWhen calling `stata_do` via MCP tool with:\n\n```json\n{\n  \"dofile_path\": \"test.do\",\n  \"log_file_name\": \"\u0027; shell echo pwned \u003e /tmp/pwned.txt; \u0027\"\n}\n```\n\nThe generated Stata commands become:\n\n```stata\nlog using \"\u003clog_dir\u003e/\u0027; shell echo pwned \u003e /tmp/pwned.txt; \u0027.log\", replace text name(text_log)\n```\n\nStata interprets this as multiple commands, with `shell echo pwned \u003e /tmp/pwned.txt;` executed as an arbitrary shell command.\n\n### Impact\n\n- **Remote Code Execution** via `shell` command injection\n- **Arbitrary file write/overwrite** via path traversal in `log_name`\n- Complete bypass of the security guard, as the guard only validates do-file content, not wrapper parameters\n\n### Remediation / Fix\n\n1. Apply strict allowlist validation to `log_name` (only alphanumeric, underscore, dot, hyphen; max 128 chars)\n2. Resolve and verify the constructed log path remains within the intended log directory\n3. Consider generating safe internal filenames (e.g., UUIDs) instead of accepting user-defined log names for command construction\n4. Apply similar sanitization to `dofile_path` before embedding it into Stata command strings\n\n### References\n\n- Issue: #74\n- Fix commit: https://github.com/SepineTam/stata-mcp/commit/e6f945941ae0c7cf5e74a428e0b3dc82b396382f",
  "id": "GHSA-4p62-hqp5-g644",
  "modified": "2026-06-04T21:00:42Z",
  "published": "2026-06-04T21:00:42Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/SepineTam/stata-mcp/security/advisories/GHSA-4p62-hqp5-g644"
    },
    {
      "type": "WEB",
      "url": "https://github.com/SepineTam/mcp-for-stata/issues/74"
    },
    {
      "type": "WEB",
      "url": "https://github.com/SepineTam/mcp-for-stata/commit/e6f945941ae0c7cf5e74a428e0b3dc82b396382f"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/SepineTam/stata-mcp"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N",
      "type": "CVSS_V4"
    }
  ],
  "summary": "MCP-for-Stata: Command injection via log_file_name parameter in Stata command wrapper"
}



Log in or create an account to share your comment.




Tags
Taxonomy of the tags.


Loading…

Loading…

Loading…

Forecast uses a logistic model when the trend is rising, or an exponential decay model when the trend is falling. Fitted via linearized least squares.

Sightings

Author Source Type Date Other

Nomenclature

  • Seen: The vulnerability was mentioned, discussed, or observed by the user.
  • Confirmed: The vulnerability has been validated from an analyst's perspective.
  • Published Proof of Concept: A public proof of concept is available for this vulnerability.
  • Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
  • Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
  • Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
  • Not confirmed: The user expressed doubt about the validity of the vulnerability.
  • Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.

Loading…

Loading…

Loading…

Related by attack behaviour

Vulnerabilities whose description is nearest to this one in the vector space of the CIRCL/vulnerability-attack-technique-biencoder model. This is a similarity search over the bi-encoder space (plain cosine), not a classification, and it has no measured accuracy.


Loading…