PT-2026-60008 · Pypi · @Utcp/Http
Published
2026-07-13
·
Updated
2026-07-13
CVSS v3.1
4.7
Medium
| Vector | AV:N/AC:H/PR:N/UI:R/S:C/C:L/I:L/A:N |
Summary
The
utcp-http plugin is vulnerable to a blind Server-Side Request Forgery (SSRF) caused by a trust-boundary inconsistency between manual discovery and tool invocation. register manual() validates the discovery URL against an HTTPS / loopback allowlist, but call tool() and call tool streaming() reuse the resolved tool call template.url directly without revalidating. An attacker who hosts a malicious OpenAPI spec on a legitimate HTTPS endpoint can declare servers: [{ url: "http://169.254.169.254" }] (or any internal address) in the spec; the OpenAPI converter blindly trusts that value and the tool becomes a blind SSRF primitive that exposes cloud metadata, internal services, and other firewalled-only endpoints to the LLM caller.All three HTTP-class protocols (
utcp http.http, utcp http.streamable http, utcp http.sse) shared the same gap, plus a separate prefix-bypass: the previous startswith("http://localhost") check let URLs like http://localhost.evil.com through.Impact
A remote attacker who can convince the agent (via the LLM context, prompt injection, or a tool-discovery surface) to register their HTTPS OpenAPI URL can:
- Map internal networks behind the agent.
- Read AWS/GCP IAM credentials from cloud metadata endpoints (
http://169.254.169.254,http://metadata.google.internal). - Reach unauthenticated internal services (Elasticsearch, Redis HTTP, internal admin panels).
- Have responses returned to the LLM, which combined with prompt injection enables exfiltration back to the attacker.
Affected versions
utcp-http <= 1.1.1.Patched versions
utcp-http 1.1.2.Patch
Commit: 5b16e43 on
dev.- New
utcp http. securityhelper:ensure secure url(url, context=...)parses the URL withurllib.parse.urlparseand validates the hostname (not a string prefix) against the loopback set, closing thelocalhost.evil.combypass. - All three protocols call
ensure secure url(url, context="manual discovery")inregister manual(replacing the duplicated prefix check) andensure secure url(url, context="tool invocation")immediately before each aiohttp request incall tool/call tool streaming. The runtime check is the actual SSRF fix. - New regression tests in
test security.pypin the accept/reject decisions and explicitly cover the historical bypass cases.
Workarounds
For users who cannot upgrade immediately:
- Refuse to call
register manualwith any URL controlled by an untrusted party, even over HTTPS. - Restrict outbound network access from the host running the agent so internal addresses (RFC1918, 169.254.0.0/16, loopback for cloud metadata) are unreachable.
Credit
Discovered and reported by @YLChen-007 in #83.
Fix
Found an issue in the description? Have something to add? Feel free to write us 👾
Related Identifiers
Affected Products
@Utcp/Http