Security: Localhost Prefix Validation Bypass in utcp-gql and utcp-websocket
Summary
A validation bypass vulnerability exists in python-utcp 1.1.0 affecting both:
The localhost security validation relies on string prefix matching instead of validating the actual hostname/IP address.
As a result, attacker-controlled domains such as:
127.0.0.1.attacker-domain.com
or
127.0.0.1.x.x.x.sslip.io
can pass localhost validation even though they resolve to a remote host.
Affected Components
- GraphQLCommunicationProtocol._enforce_https_or_localhost()
- WebSocketCallTemplate.validate_url()
Root Cause
The implementation allows URLs beginning with:
using string prefix checks.
This does not verify that the hostname is actually a loopback address.
Example:
http://127.0.0.1.attacker-domain.com/graphql
The URL begins with "http://127.0.0.1/" and therefore passes validation, but the request is sent to a remote server.
Impact
If an attacker can influence endpoint URL configuration, authenticated requests may be redirected to attacker-controlled infrastructure.
Potential consequences include:
- Authorization header disclosure
- API key leakage
- Tool-call data exposure
- Security control bypass
Reproduction
A proof-of-concept was successfully reproduced using a crafted sslip.io hostname:
127.0.0.1..sslip.io
The URL passes validation and receives authenticated GraphQL/WebSocket traffic from the client.
Observed behavior:
- Validation succeeds
- Requests are sent to a non-loopback host
- Authorization headers are transmitted to the remote endpoint
Suggested Fix
-
Parse URLs using a proper URL parser.
-
Validate the actual hostname rather than performing string prefix matching.
-
Only allow exact loopback hosts:
-
Add regression tests for:
- localhost.attacker.tld
- 127.0.0.1.attacker.tld
- 127.0.0.1.x.x.x.sslip.io
Environment
- python-utcp 1.1.0
- utcp-gql 1.1.0
- utcp-websocket 1.1.0
I can provide the complete PoC and test output if additional information is required.
Security: Localhost Prefix Validation Bypass in utcp-gql and utcp-websocket
Summary
A validation bypass vulnerability exists in python-utcp 1.1.0 affecting both:
The localhost security validation relies on string prefix matching instead of validating the actual hostname/IP address.
As a result, attacker-controlled domains such as:
127.0.0.1.attacker-domain.com
or
127.0.0.1.x.x.x.sslip.io
can pass localhost validation even though they resolve to a remote host.
Affected Components
Root Cause
The implementation allows URLs beginning with:
using string prefix checks.
This does not verify that the hostname is actually a loopback address.
Example:
http://127.0.0.1.attacker-domain.com/graphql
The URL begins with "http://127.0.0.1/" and therefore passes validation, but the request is sent to a remote server.
Impact
If an attacker can influence endpoint URL configuration, authenticated requests may be redirected to attacker-controlled infrastructure.
Potential consequences include:
Reproduction
A proof-of-concept was successfully reproduced using a crafted sslip.io hostname:
127.0.0.1..sslip.io
The URL passes validation and receives authenticated GraphQL/WebSocket traffic from the client.
Observed behavior:
Suggested Fix
Parse URLs using a proper URL parser.
Validate the actual hostname rather than performing string prefix matching.
Only allow exact loopback hosts:
Add regression tests for:
Environment
I can provide the complete PoC and test output if additional information is required.