CVE-2026-44661 — utcp-http
MEDIUMCVE-2026-44661 is a medium-severity (CVSS 4.7) Server-Side Request Forgery (SSRF) vulnerability in utcp-http. A fix is available for utcp-http — see the affected versions and patch details below.
utcp-http vulnerable to SSRF via attacker-controlled OpenAPI servers[0].url in HTTP communication protocol
Exploitation Status
No confirmed exploitation observed yet
- CISA’s own triage has not observed active exploitation or public proof-of-concept code for this CVE as of its last assessment.
Exploitation and automatability from CISA’s SSVC triage for CVE-2026-44661.
EPSS Exploitation Probability
Probability of exploitation in the next 30 days, from FIRST.org EPSS.
How urgent is this, really
Where this sits among everything scored
Real-World Exposure
utcp-httpReal-time download stats are indexed for npm and PyPI packages. This vulnerability affects PyPI packages — download data is not available via public APIs for these ecosystems.
Description
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.
Affected Packages
| Ecosystem | Package | Vulnerable range | Fix |
|---|---|---|---|
| 🐍PyPI | utcp-http | all versions | 1.1.2pip install --upgrade 'utcp-http==1.1.2' |
Detection & mitigation playbook
Open-source dependencyDetect
Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for utcp-http, including transitive dependencies — a direct dependency you never call can still pull in a vulnerable version.
Fix
Update utcp-http to 1.1.2 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms CVE-2026-44661 is resolved across your whole dependency graph.
Workarounds
Restrict outbound requests from the affected component to an allowlist of hosts, block access to link-local and internal address ranges at the network layer, and require authentication on internal services so a forged request cannot reach them unauthenticated.
Frequently Asked Questions
Is CVE-2026-44661 in your dependencies?
Find it across PyPI, including transitive dependencies.