MCP-SERVER-FETCH · GHSA-3rxj-6jhw-qfv7 · AI agents & MCP
FIX → 2026.11.11
The fetch tool's address check treats the deprecated IPv6 site-local range fec0::/10 as public, so a request to a site-local address passes the guard. An attacker who can drive the fetch tool could reach a non-public IPv6 destination, though the advisory says default hosts usually have no route there.
first public Nov 11, 2026 · 1 source
Could this affect your app?
Free first check from your website. Connect your repo for the full answer.
Teams that run mcp-server-fetch, the PyPI MCP server that fetches URLs for an AI agent, and rely on its address guard to refuse non-public destinations. Exposure depends on whether the host has a route to fec0::/10; the advisory says it usually does not on a stock modern kernel. Teams not running this package can skip it.
Not affected if default-config, no-ipv6-route
Who cares mcp, mcp-server-fetch, python
pip show mcp-server-fetch and check whether the version is >= 2026.10.10 and < 2026.11.11.python -c "from mcp_server_fetch.server import _is_public_address as f; print(f('fec0::1'))" and a True result means the guard is affected.Upgrade to 2026.11.11
_is_public_address in mcp-server-fetch omits fec0::/10 (deprecated IPv6 site-local) and ::ffff:0:0/96 from its non-public list and falls back to ip.is_global, which returns True for fec0::1. A fetch to http://[fec0::1]/ passes the SSRF guard. Low real-world reachability on default hosts; this is a classifier-correctness gap, not a proven metadata exploit.
Server: fetch (mcp-server-fetch, PyPI)
Affected versions: 2026.11.4 and 2026.10.24 (reproduced on both)
CWE: CWE-918 (SSRF — guard classifier gap)
_is_public_address (src/mcp_server_fetch/server.py) unwraps IPv4-mapped and well-known NAT64 forms and lists many non-public ranges, but omits fec0::/10 (deprecated IPv6 site-local, RFC 3879) and ::ffff:0:0/96 (IPv4-translated). It then falls back to return ip.is_global and not ip.is_multicast, and Python's ipaddress reports fec0::1 as is_global == True. So a to passes the guard that is meant to refuse non-public destinations.
Check it with your coding agent
It reads this page and tells you if your code is affected.
Are you affected?
Ask from here. InfraStack checks the affected versions against your stack and answers in your inbox.
InfraStack checks the affected versions against your stack and answers in Slack, with the evidence and the fix.
mcp-server-fetch 2026.11.11fetchhttp://[fec0::1]/…This is a guard-classifier correctness issue — the guard's own threat model includes non-public destinations — not a proven metadata-service exploit on default hosts. On a stock modern kernel fec0::1 usually has no route and the connection times out; the translated loopback form [::ffff:0:127.0.0.1] was correctly normalized and blocked. Every other loopback / RFC1918 / link-local / redirect form in a 36-case matrix (2-hop, protocol-relative, 307/308, userinfo, trailing-dot and uppercase-host redirects, 0.0.0.0, [::], full-octal IPv4, mapped / NAT64) was correctly refused.
The SSRF allowlist classifies a non-public (site-local) IPv6 destination as public. Severity is Low given the limited default-host reachability; it is a defense-in-depth / correctness gap in a guard whose purpose is to deny non-public destinations.
Explicitly block fec0::/10 and ::ffff:0:0/96; deny-by-default on not ip.is_global combined with reserved / site-local checks rather than relying on is_global alone.
Reported privately per SECURITY.md. Analysis and drafting were AI-assisted and reviewed by a human researcher at ShieldPi. Credit, if accepted: ShieldPi (support@shieldpi.io).
The SSRF guard classifies a non-public IPv6 site-local address (fec0::1) as a public destination, so a fetch to it bypasses the guard. Real-world reachability is low on default hosts (no route to fec0::/10); impact is a classifier-correctness / defense-in-depth gap, not a proven metadata-service read. Affects any deployment relying on mcp-server-fetch's address guard to refuse non-public destinations.