VYPR
Medium severity6.3NVD Advisory· Published Jun 15, 2026

CVE-2026-12210

CVE-2026-12210

Description

A server-side request forgery vulnerability in python-utcp 1.1.0 allows attackers to bypass localhost validation and redirect authenticated requests to attacker-controlled servers.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

A server-side request forgery vulnerability in python-utcp 1.1.0 allows attackers to bypass localhost validation and redirect authenticated requests to attacker-controlled servers.

Vulnerability

In python-utcp 1.1.0, the GraphQL and WebSocket protocol handlers (utcp-gql and utcp-websocket) use string prefix matching to allow localhost URLs (e.g., http://localhost, http://127.0.0.1, ws://localhost, ws://127.0.0.1). This allows crafted domains like 127.0.0.1.attacker.com to bypass validation. Affected versions: utcp-gql 1.1.0 and utcp-websocket 1.1.0. [2][3]

Exploitation

An attacker who can influence the endpoint URL configuration (e.g., via a malicious tool definition or configuration) can supply a URL such as http://127.0.0.1.attacker-domain.com/graphql. The prefix check passes, and the client sends authenticated requests to the attacker's server. No authentication or user interaction required beyond the ability to set the URL. [2][3]

Impact

Successful exploitation leads to server-side request forgery (SSRF). The attacker can receive sensitive headers (e.g., Authorization, API keys), request content, and internal tool-call data. This can result in disclosure of credentials and data, and bypass of security controls intended to restrict communication to localhost. [2][3]

Mitigation

No official fix has been released as of the publication date (2026-06-15). The vendor did not respond to disclosure. The suggested fix is to parse URLs properly and validate the actual hostname, allowing only exact loopback addresses (localhost, 127.0.0.1, ::1). Users should avoid using the affected plugins or restrict endpoint URL configuration to trusted sources until a patch is available. [2][3]

AI Insight generated on Jun 15, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected products

2

Patches

0

No patches discovered yet.

Vulnerability mechanics

Root cause

"String prefix matching instead of proper hostname/URL parsing allows crafted domains beginning with `127.0.0.1.` or `localhost.` to bypass localhost validation."

Attack vector

An attacker who can influence the endpoint URL configuration supplies a crafted domain such as `127.0.0.1.attacker-domain.com` or `127.0.0.1.x.x.x.sslip.io` [ref_id=1][ref_id=2]. Because the validation uses string prefix matching, a URL like `http://127.0.0.1.attacker-domain.com/graphql` passes the localhost check even though it resolves to a remote attacker-controlled server [ref_id=1][ref_id=2]. The client then sends authenticated requests—including Authorization headers containing API keys—to the attacker's infrastructure, leaking sensitive credentials and tool-call data [ref_id=1][ref_id=2]. No authentication is required to exploit the validation bypass itself, though the attacker must control the URL input path [ref_id=1].

Affected code

The vulnerability resides in `GraphQLCommunicationProtocol._enforce_https_or_localhost()` (file `plugins/communication_protocols/gql/src/utcp_gql/gql_communication_protocol.py`) and `WebSocketCallTemplate.validate_url()` (file `plugins/communication_protocols/websocket/src/utcp_websocket/websocket_call_template.py`) [ref_id=1][ref_id=2]. Both functions use Python's `startswith()` string matching to allow URLs beginning with `http://localhost`, `http://127.0.0.1`, `ws://localhost`, or `ws://127.0.0.1` without verifying the actual hostname [ref_id=1][ref_id=2].

What the fix does

No patch has been published by the vendor; the advisory recommends parsing the URL with a strict URL parser and validating the hostname semantically rather than using string prefix matching [ref_id=1][ref_id=2]. The suggested fix is to allow only exact loopback hosts (`localhost`, `127.0.0.1`, `::1`), optionally resolve DNS and reject non-loopback resolved IPs, and add regression tests for crafted domains such as `127.0.0.1.attacker.tld` and `localhost.attacker.tld` [ref_id=1][ref_id=2].

Preconditions

  • inputAttacker must be able to influence the endpoint URL configuration (e.g., supply a malicious URL to the GraphQL or WebSocket call template).
  • authNo authentication is required to trigger the validation bypass itself.

Reproduction

1. Set up the environment: create a Python virtual environment, install `python-utcp` and the `utcp-gql` and `utcp-websocket` plugins from source [ref_id=1]. 2. Run the PoC script `/tmp/utcp_poc_sslip_bypass.py` (provided in the advisory) which crafts a domain like `127.0.0.1.<ip>.sslip.io` and creates `GraphQLCallTemplate` and `WebSocketCallTemplate` objects with that URL and an `ApiKeyAuth` header [ref_id=1]. 3. Observe that validation succeeds, requests are sent to the non-loopback host, and the Authorization headers (`LEAKED_GQL_SECRET`, `LEAKED_WS_SECRET`) are transmitted to the attacker-controlled server [ref_id=1].

Generated on Jun 15, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

6

News mentions

0

No linked articles in our index yet.