CVE-2026-104120 lets an agent steer the official MCP fetch tool to internal and cloud metadata addresses. A public exploit exists; fix PR #4890 is unmerged.
CVE-2026-104120 is a server-side request forgery flaw in the fetch_url function of the Model Context Protocol reference fetch server. NVD lists mcp-server-fetch and mcp-server-everything versions up to 2026.6.4 as affected (the record appears to merge two separate bugs, explained below), says an exploit has been disclosed publicly, and notes that the fix pull request "awaits acceptance." As of 4 October 2026 that pull request is still an unmerged draft.
What happened
NVD published the record on 2 October 2026 on behalf of VulDB, which is the CNA. The description places the flaw in mcp_server_fetch/server.py, in the Fetch Tool component, where, in NVD's words, manipulating "the argument url/path" leads to SSRF. It is remotely reachable, according to the record.
The scoring comes from VulDB, not NVD, and NVD has marked the record "Deferred," meaning it has not done its own analysis. VulDB assigns CVSS 3.1 7.3 (High, CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:L) and CVSS 4.0 5.5 (Medium, with exploit maturity set to proof of concept). The weakness is CWE-918. The CVE is not in CISA's Known Exploited Vulnerabilities catalog, and we found no report of exploitation in the wild.
Why it matters
The fetch server exists so that a model can retrieve a URL it chooses. That makes the URL attacker-influenced whenever the model reads untrusted content: a web page, an email, a ticket or a document can carry instructions that steer the agent toward an internal address. The server then makes the request from wherever it runs, with that host's network position.
This is inference from how the tool works rather than a documented attack, but the exposure follows the deployment. A fetch server on a developer laptop can reach local services. One in a cloud VM or container can reach the instance metadata endpoint, which is the usual route to temporary credentials. One in a cluster can reach internal APIs that were never meant to be internet-facing. Anyone running these servers behind an agent that also reads untrusted input is the most exposed group. (We covered a similar network-exposed MCP Atlassian server flaw earlier.)
The CVSS vectors show low confidentiality, integrity and availability impact and no privileges required. The scores say little about your risk: what matters is what the host can reach.
Where egress filtering and IMDSv2 cut the fetch SSRF chain.
Technical details
The most likely source of the "public exploit" is issue #4492, which NVD cites. The issue is titled "GHSAs" and was opened on 8 July. On 4 September the reporter, geo-chen, posted three write-ups in a comment on it. Per the issue, the reporter submitted them privately on 5 June, a day after 2026.6.4 shipped. We see no maintainer reply on the issue. The CVE followed on 2 October. We could not read VulDB's entry (HTTP 403), so the link between the CVE and this issue is our inference from NVD's reference list and the matching content.
One write-up describes fetch_url near line 119 of mcp_server_fetch/server.py. It says the tool does no loopback, link-local, metadata or private-range filtering, follows redirects without re-validating the target, and that the robots.txt pre-check in check_may_autonomously_fetch_url uses the same unguarded client. It reports a proof of concept reproduced on 2026.6.4 against a stand-in internal endpoint on 127.0.0.1. We link the issue and do not reproduce the code. The reporter notes that file:// and gopher:// are rejected, so this is HTTP/HTTPS request forgery, not local file read.
Issue #4838, filed on 22 September, independently describes the same behavior in reviewed September code: follow_redirects=True and no destination checks, so model-controlled URLs can reach loopback, RFC 1918, link-local and cloud-metadata addresses. Because redirects are followed, an allowlist applied only to the first URL would not be enough.
The everything server is a different bug. fetch_url is in the fetch server. The same #4492 comment describes a separate SSRF in the everything server's gzip-file-as-resource tool (npm @modelcontextprotocol/server-everything, confirmed by the reporter on 2026.1.26). Its GZIP_ALLOWED_DOMAINS allowlist is empty by default, and empty means all domains are allowed. Current main still applies the check only when the list is non-empty. NVD's record appears to fold both reports into one CVE.
Newer releases. NVD lists only 2026.6.0 through 2026.6.4. PyPI also has mcp-server-fetch 2026.7.10 and 2026.8.18. We inspected the 2026.8.18 wheel: its server.py still calls client.get(..., follow_redirects=True) in two places, with no IP or private-range check anywhere. By our own inspection the latest release has the same unguarded code, even though NVD does not list it. Upgrading does not help.
Why there is no fix. The fetch server README carries a caution: "This server can access local/internal IP addresses and may represent a security risk." The author of the pending patch cites that line as a reason maintainers may not want blocking on by default.
Draft pull request #4890, opened on 28 September, would resolve names and block private ranges before connecting, re-check every redirect hop, and add an FETCH_ALLOW_PRIVATE_IPS=1 escape hatch. It also lists the non-AWS metadata address 100.100.100.100. It carries 43 unit tests. Its author asks maintainers whether blocking should be the default, opt-in, or not done at all, because some users deliberately fetch from http://localhost:8000, and says the patch does not fully close DNS-rebinding (time-of-check, time-of-use) gaps. No maintainer decision is visible.
What defenders should do
No patched release exists, so mitigation sits outside the tool. These are general hardening measures, not vendor guidance.
- Inventory. Find where
mcp-server-fetchormcp-server-everythingruns, including agent frameworks and IDE integrations that launch it on demand. - Restrict egress. Run the server in a network segment that cannot reach internal ranges, and allow outbound traffic only to what the agent needs. Do this at the network layer so redirects cannot bypass it.
- Block the metadata address. Deny
169.254.169.254and the equivalent endpoints (such as100.100.100.100, which the PR also lists) from the process or container. On AWS, require IMDSv2 and set the hop limit to 1 so containers cannot reach the service. - Everything server. Set
GZIP_ALLOWED_DOMAINSto an explicit list, or do not run the everything demo server where it can reach internal networks. - Isolate. Use a dedicated host or sandbox with no credentials, no attached cloud role and no access to the corporate network.
- Limit the tool. Disable the fetch tool for agents that process untrusted content, or require human approval for each fetch (see runtime authorization for MCP tool calls).
- Watch. Alert on requests from agent hosts to loopback, RFC 1918, link-local and metadata addresses.
- Track the fix. Follow PR #4890 and issues #4838 and #4492. If it merges with the block as opt-in, you will still need to turn it on.
What is still unclear
- Which release will carry a fix, and whether maintainers will make private-address blocking the default.
- Whether VulDB's entry points to issue #4492 as the exploit. We could not read it.
- Whether anyone is exploiting it. Nothing we found says so.