1. Executive summary
CVE-2026-44661 is a CWE-918 server-side request forgery vulnerability affecting utcp-gql 1.1.0 and utcp-websocket 1.1.0; both are fixed in 1.1.1. The verified rating is CVSS 4.7 MEDIUM; it is NOT in CISA KEV, and EPSS is 0%. An attacker who can influence a UTCP tool manual can direct GraphQL or WebSocket connections to internal services, loopback addresses or cloud metadata endpoints and may receive API keys, Basic credentials or OAuth bearer tokens attached to the connection. EMEA financial-services exposure is conditional on use of these plugins, acceptance of attacker-influenced manuals, internal network reachability and configured authentication headers. The vulnerable paths, proof of concept and patch details are single-sourced to the GitHub advisory; the supplied sources provide no evidence of exploitation in the wild or actor attribution.
2. Regulatory framing
No specific DORA/NIS2 article is directly engaged by this item. The supplied facts also do not establish a trigger for UK NIS 2018: UK Network and Information Systems Regulations — OES/RDSP duties.
Clients should reassess incident-classification and reporting obligations if investigation identifies credential disclosure, unauthorised internal access, service impact or exploitation in a regulated service.
3. Technical analysis & attack chain
The authoritative vulnerability metadata is CVE-2026-44661 — CVSS 4.7 MEDIUM — NOT in CISA KEV — EPSS 0% — CWE-918 (Server-Side Request Forgery).
Identifier discrepancy: the supplied external rendering labels GHSA-ppx3-28rw-8fpf as CVE-2026-12210, while the authoritative reference supplied for this advisory identifies CVE-2026-44661. This advisory uses CVE-2026-44661 and its verified metadata; clients should also retain the GHSA identifier when searching SBOM and advisory tooling.
Source-confirmed attack chain
- Required initial condition: an attacker supplies or influences a UTCP tool manual containing a GraphQL or WebSocket call-template
url. The source does not establish a direct, unauthenticated network exploit against UTCP itself. - GraphQL validation bypass:
plugins/communication_protocols/gql/src/utcp_gql/gql_communication_protocol.pyapplies_enforce_https_or_localhost()tomanual_call_template.urlinregister_manualat line 102 and totool_call_template.urlincall_toolat line 181. The validator uses string prefixes:
python url.startswith("https://") or url.startswith("http://localhost") or url.startswith("http://127.0.0.1")
Consequently, http://127.0.0.1.attacker.example/graphql and http://localhost.evil.com/graphql pass validation even though their parsed hostnames are not loopback hosts.
- GraphQL connection: the accepted URL is passed to
AIOHTTPTransportand used for a live GraphQL request. If the attacker controls the hostname’s DNS, the source states it can resolve to169.254.169.254,127.0.0.1or an internal192.168.x.xaddress reachable from the UTCP runtime. - WebSocket validation omission:
plugins/communication_protocols/websocket/src/utcp_websocket/websocket_communication_protocol.pyclaims to enforce “WSS or localhost only,” but_get_connection()performs no scheme or hostname validation. This shared connection path is used byregister_manual,call_toolandcall_tool_streamingand calls:
python ws = await session.ws_connect(call_template.url, headers=headers, ...)
A WebSocketCallTemplate can therefore specify direct destinations such as ws://169.254.169.254/, ws://127.0.0.1:<internal-port>/ or an internal hostname.
- Credential attachment and impact: both plugins use
_prepare_headers()before connecting.ApiKeyAuthis attached as a configured header,BasicAuthasAuthorization: Basic, andOAuth2AuthasAuthorization: Bearer. When the destination is an attacker-controlled host, these credentials can be delivered to that host over plain HTTP or WebSocket. Connections to internal targets can expose otherwise unreachable services or metadata endpoints to attacker-directed requests. - Exploitation state: CVE-2026-44661 is CVSS 4.7 MEDIUM, NOT in CISA KEV, and has EPSS 0%. The supplied material demonstrates the vulnerable code paths and a proof of concept but contains no incident telemetry showing exploitation against production systems.
Affected and fixed versions
| Package | Affected version established by source | Fixed version | Fix |
|---|---|---|---|
utcp-gql |
1.1.0 | 1.1.1 | Replaces prefix validation with hostname-based ensure_secure_url at register_manual and call_tool; refuses GraphQL endpoint 3xx responses after connection. |
utcp-websocket |
1.1.0 | 1.1.1 | Adds ensure_secure_ws_url in the Pydantic field validator and _get_connection; calls ws_connect with allow_redirects=False; uses redirect-safe OAuth2 token retrieval. |
The source does not define the status of versions earlier than 1.1.0; do not infer an affected range beyond the stated version. Both plugins duplicate _security.py from utcp-http rather than introducing a runtime dependency, creating a requirement to keep validator behaviour synchronised.
A separate advisory concerning utcp-http documents SSRF through unvalidated HTTP redirects. It supports the need for redirect controls but does not independently corroborate the GraphQL and WebSocket findings.
No malware, persistence, privilege escalation, command-and-control, lateral movement or ransomware behaviour is reported. No confirmed data theft or operational disruption is documented. The plugin findings remain single-sourced; verify affected code and runtime behaviour before enforcement.
4. Mitigation & containment
P1 — within 24 hours
- Inventory installed versions:
bash python -m pip show utcp-gql utcp-websocket
- On deployments that accept externally supplied or otherwise attacker-influenced manuals, upgrade each installed affected package immediately:
bash python -m pip install --upgrade "utcp-gql>=1.1.1" "utcp-websocket>=1.1.1"
Update the applicable lockfile or image definition and rebuild/restart the deployed workload; do not rely solely on changing an unused local environment.
- If immediate upgrade is impossible, disable the affected plugin or suspend registration and invocation of untrusted manuals. The vendor states that no workaround exists for earlier versions; disabling use and restricting egress are containment measures only.
- Restrict the UTCP workload’s outbound access to approved tool endpoints. Block its access to cloud metadata, loopback and internal services not explicitly required. Do not use string-prefix hostname rules.
- If suspicious manual URLs or connections are identified, revoke and rotate any API keys, Basic credentials and OAuth2 tokens attached to those call templates.
P2 — within 72 hours
- Upgrade remaining
utcp-gqlandutcp-websocket1.1.0 deployments to 1.1.1 or later and confirm the running environment, container or virtual environment loads the fixed package. - Search stored manuals and call-template configuration for:
http://localhost.andhttp://127.0.0.1.hostnames;- cleartext
ws://URLs targeting169.254.169.254, loopback or internal hosts; - destinations outside the approved endpoint inventory.
- Review UTCP application, DNS, proxy and network telemetry for manual registration followed by connections to those destinations. The source supplies no standard UTCP log path or event identifier.
- Confirm that GraphQL redirects are refused and that WebSocket connections use both the field validator and
_get_connectionvalidation. Preserve relevant logs before rotating credentials.
P3 — within seven days
- Add regression tests using the published bypass URLs and verify they are rejected. Include direct internal WebSocket URLs and 3xx redirect tests.
- Enforce destination policy using parsed schemes and hostnames, resolved-address checks and redirect controls. Treat manual-provided URLs as untrusted input.
- For maintained forks, keep the duplicated
_security.pyimplementations aligned withutcp-http; GraphQL must useensure_secure_url, while WebSocket must useensure_secure_ws_urlandallow_redirects=False. - Reduce credential scope for tool integrations and separate UTCP workloads from sensitive internal management services and metadata endpoints.
5. Indicators of compromise
No indicators of compromise available in the source material.
The following are published proof-of-concept behaviours, not confirmed malicious infrastructure. The evidence is single-sourced; verify before enforcement.
Behavioural indicators
| Behaviour | Where to observe | Confidence |
|---|---|---|
GraphQL call-template URL resembling hxxp://127[.]0[.]0[.]1[.]attacker[.]example/graphql or hxxp://localhost[.]evil[.]com/graphql |
Stored UTCP manuals, registration logs, application URL telemetry, DNS logs | High for vulnerable behaviour; single-source code path and PoC, not proof of compromise |
utcp-websocket initiates a cleartext connection such as ws[:]//169[.]254[.]169[.]254/ or to loopback/internal services |
Endpoint network telemetry, container network telemetry, proxy logs where WebSocket traffic is captured | High for published PoC behaviour; single-sourced |
API-key headers or Authorization: Basic/Authorization: Bearer are sent to a destination outside the approved tool inventory |
HTTP/WebSocket metadata and application telemetry; avoid recording raw credential values | Medium; capability established by source, with no observed exploitation |
Source: GitHub Security Advisory GHSA-ppx3-28rw-8fpf.
6. Detection
No YARA rule is appropriate because the source provides no malicious-file artefacts. The package paths and product/CVE names describe vulnerable software, not attacker payloads.
The following Sigma rule targets the exact published URL forms. Map url to the corresponding field in local UTCP, proxy or application telemetry.
title: UTCP GraphQL and WebSocket SSRF Published URL Patterns
status: experimental
description: Detects URL patterns published for the utcp-gql prefix bypass and utcp-websocket direct internal connection.
references:
- https://github.com/advisories/GHSA-ppx3-28rw-8fpf
author: Adverse Trace
date: 2026-08-25
logsource:
category: proxy
detection:
selection_graphql_prefix:
url|startswith:
- 'http://127.0.0.1.'
- 'http://localhost.'
selection_websocket_internal:
url|startswith:
- 'ws://169.254.169.254/'
- 'ws://127.0.0.1:'
condition: selection_graphql_prefix or selection_websocket_internal
falsepositives:
- Controlled testing using the published proof of concept
level: medium
This rule covers only the published forms. WebSocket exploitation can use other reachable internal hostnames, while loopback and link-local traffic may bypass central proxies; deploy equivalent application and endpoint-network monitoring around the UTCP runtime.
CVE assessment
1 referenced CVE
| CVE | CVSS | Exploited | EPSS | Summary |
|---|---|---|---|---|
| CVE-2026-44661 | 4.7 Medium | — | 0% | python-utcp is the python implementation of UTCP. Prior to 1.1.3, the utcp-http plugin is vulnerable to a blind Server-Side Req… |
7. Sources
- GitHub Security Advisories, “utcp-gql SSRF: CVE-2026-44661 fix not applied to the GraphQL and WebSocket plugins,” https://github.com/advisories/GHSA-ppx3-28rw-8fpf, 25 August 2026.
- GitHub Security Advisories, “utcp-http SSRF: HTTP tool invocation follows redirects without re-validating the target,” https://github.com/advisories/GHSA-9qhg-99ww-9mqc, date not provided in the supplied extract.
8. Adverse Trace position
Adverse Trace retains the verified rating of CVSS 4.7 MEDIUM for CVE-2026-44661; it is NOT in CISA KEV, has EPSS 0%, and is classified as CWE-918. Client impact is conditional but material where affected UTCP deployments ingest attacker-influenced manuals, possess sensitive tool credentials and can reach internal services. We recommend immediate upgrade for deployments meeting those conditions and completion within 72 hours elsewhere, without elevating the issue to critical or treating the proof of concept as evidence of active exploitation. The specific plugin findings remain single-sourced; verify before enforcement. Adverse Trace will monitor the GHSA identifier discrepancy, maintainer releases, CISA KEV status, EPSS and credible exploitation reporting.
Published via PulseTrace — Adverse Trace threat intelligence.