---
title: "MCP Fetch Server SSRF - CVE-2026-104120: Fix Merged, No Release Yet | Anomity Blog"
description: "CVE-2026-104120: the reference MCP fetch server can be steered to localhost and cloud metadata. A fix merged Oct 5 on v2/main; PyPI 2026.8.18 lacks it."
url: "https://anomity.ai/blog/mcp-server-fetch-ssrf-cve-2026-104120/"
source: html
---

On this page

- What to do now
- How Anomity surfaces and governs it
- What the reporter found
- The fix, and what it leaves open
- Why a README caution is not a control
- Frequently asked questions

[← Back to blog](https://anomity.ai/blog/)

- Home

- Blog

- MCP Fetch Server SSRF - CVE-2026-104120: Fix Merged, No Release Yet

![Anomity robot illustrating MCP Fetch Server SSRF - CVE-2026-104120: Fix Merged, No Release Yet]

Insights

# MCP Fetch Server SSRF - CVE-2026-104120: Fix Merged, No Release Yet

Anomity Research
Anomity Research
·
Oct 5, 2026
·
5 min read

Share: Copied

TL;DR

- CVE-2026-104120 (published October 2, 2026 , CVSS 3.1 7.3 ) is an SSRF in the official mcp-server-fetch reference server. NVD lists versions up to 2026.6.4 . Action now: on any host with internal services or cloud metadata, restrict or remove the fetch server until a fixed release ships.
- The fetch tool requested any URL the model supplied, followed redirects without re-checking the destination , and ran its robots.txt pre-check through the same unguarded client. Loopback, RFC 1918 and 169.254.169.254 were all reachable.
- Because the URL comes from the model, prompt injection in a page or document the agent reads can aim it at internal services and pull the response into the model's context.
- A fix ( PR #5033 ) merged on October 5 to the v2/main branch: every request and redirect hop is refused if the host resolves to a non-public address, unless the server starts with --allow-private-ips . As of October 5 the latest PyPI release, 2026.8.18 , predates it.
- The fix's own notes name two limits: a DNS-rebinding window between check and connect, and names the server cannot resolve pass through . Treat it as defense in depth, not a reason to expose fetch next to metadata.

**The short version:** the official MCP fetch server will fetch whatever URL the model gives it, including `http://127.0.0.1` and the cloud metadata endpoint. **CVE-2026-104120**, published **October 2, 2026**, puts a number on that. A fix merged on **October 5**, but as of that date it is **not in a released version**. Until it is, keep mcp-server-fetch away from hosts with internal services or cloud metadata.

The record comes from VulDB as CNA: **CVSS 3.1 7.3**, CVSS 4.0 5.5, CWE-918, affecting **mcp-server-fetch and mcp-server-everything up to 2026.6.4**, function `fetch_url` in `mcp_server_fetch/server.py`. It says an exploit has been disclosed publicly. GitHub tracks it as **GHSA-v78q-44mm-wf7q** and rates it Medium.

## What to do now

- Find every client that launches mcp-server-fetch , on laptops and on any server or CI runner with an MCP client.
- On cloud hosts , do not run it next to the instance metadata endpoint. Remove it, or block egress to 169.254.169.254 and private ranges at the host or network layer.
- On laptops, assume it can reach local services : dev databases, admin panels, other MCP servers on localhost.
- When a release containing PR #5033 ships, upgrade, and do not add --allow-private-ips unless a specific workflow needs it.

## How Anomity surfaces and governs it

**See it.** The fetch server ships in the official reference servers repository, which makes it an easy default to copy into a client config. The Endpoint Sensor inventories the MCP servers configured on each managed endpoint, with versions, so "who runs fetch?" is a query rather than a survey. Metadata only; secrets are redacted on the endpoint.

**Enforce before the call runs.** On agents that expose a pre-execution hook, such as Claude Code PreToolUse, Anomity can **allow, deny or log** a fetch tool call before it runs. That is an independent control from the server's own address check, which matters while the fix is unreleased and after it, given the limits below. Decisions land in a 90-day audit trail and route to SIEM, Slack, email or Jira.

## What the reporter found

The reporter, posting on the project's issue tracker, says private reports were submitted on **June 5, 2026**, the day after 2026.6.4 shipped, and published the write-ups in a public comment on **September 4**. The core finding: `fetch_url` passed the caller's URL to an HTTP client with `follow_redirects=True` and **no host or IP validation anywhere in the module**. The only check was a syntactic URL type.

- Direct internal fetches: loopback, RFC 1918, 0.0.0.0 and link-local metadata addresses were all requested as normal.
- Redirects: a public-looking URL that returns a 302 to an internal address was followed without re-validation.
- The robots.txt gate used the same unguarded client, so even the pre-flight check reached an attacker-chosen host.
- Not a file read: file:// and gopher:// are rejected by the HTTP library, so this is HTTP and HTTPS SSRF.

The reporter reproduced it on 2026.6.4 by pointing `fetch_url` at a local stand-in for a metadata endpoint and getting the body back. In an agent, the attacker does not call the tool directly. They plant instructions in content the agent reads, and the model makes the call. This is the [lethal trifecta](https://anomity.ai/blog/lethal-trifecta-ai-agent-data-exfiltration/) in miniature: untrusted input, access to private data, and a way to send it out.

## The fix, and what it leaves open

**PR #5033** merged into the `v2/main` branch on **October 5, 2026**, closing issue #4838. It adds an HTTP request hook that resolves each request's host and refuses the request if **any** resolved address is not globally routable. Because the hook runs before every request, it covers the robots.txt check, the page fetch and **every redirect hop**. The blocked set follows the IANA special-purpose ranges, including `169.254.0.0/16`, `100.64.0.0/10` and IPv6 unique-local addresses, which between them cover the AWS, GCP, Azure and Alibaba Cloud metadata addresses the PR lists.

A new **--allow-private-ips** flag restores the old behavior. It is a command-line flag rather than a tool argument, so the model cannot switch it off. The PR is explicit about two limits:

- DNS rebinding (time-of-check, time-of-use). The hook resolves the name, then the HTTP client resolves it again to connect. A hostile DNS server can answer differently the second time.
- Unresolvable names fail open. A name the server cannot resolve is passed through, which matters with --proxy-url , where the proxy does the resolving.

Two practical caveats. First, the fix landed on `v2/main`, the branch for the reference servers' move to the [2026-07-28 MCP specification](https://anomity.ai/blog/stateless-mcp-2026-07-28-spec-security/), not on `main`. Second, as of October 5 the newest mcp-server-fetch on PyPI is **2026.8.18**, from August 18. There is no fixed version to pin yet. This is the same pattern we documented in [MarkItDown and MCP SSRF at ecosystem scale](https://anomity.ai/blog/mcp-furi-markitdown-ssrf-ecosystem-scale/): a URL-taking tool that trusts the model, copied from one config to the next.

## Why a README caution is not a control

The fetch server's README warns that it "can access local/internal IP addresses and may represent a security risk." That warning was accurate, and it changed nothing for anyone who copied the server into a config without reading it. Insecure defaults in reference implementations spread, because reference implementations are what people start from. The same is true of [local MCP servers that trusted DNS](https://anomity.ai/blog/mcp-local-http-dns-rebinding-class-2026/).

The controls that hold are the boring ones: know where the server runs, keep it off hosts with metadata, block private egress below the application, and decide on the tool call before it runs. For the wider MCP control set, see [model context protocol security explained](https://anomity.ai/blog/model-context-protocol-mcp-security-explained/). To find every fetch server configured across your endpoints, [book a 30-minute demo](https://anomity.ai/#early-access).

Share: Copied

## Frequently asked questions

Am I affected by CVE-2026-104120?
If an MCP client on a machine or server launches mcp-server-fetch, assume yes until a release containing PR #5033 ships. NVD lists versions up to 2026.6.4, but the fix was merged only on October 5, 2026, and the latest version on PyPI on that date was 2026.8.18, published August 18. The exposure that matters most is where the fetch server runs: on a laptop it can reach local services, and on a cloud host it can reach the instance metadata endpoint.

Is this a new bug?
Not entirely. The fetch server's README carries a caution that it can access local and internal IP addresses and may represent a security risk. What changed is that the behavior now has a CVE, a public write-up and a merged fix. The reporter says private reports were submitted on June 5, 2026 and posted the write-ups publicly on the project's issue tracker on September 4.

How does prompt injection turn into SSRF here?
The fetch tool's URL argument is chosen by the model. If the agent reads a web page, issue or document containing instructions to fetch an internal address, the model can call the fetch tool with that address and the response comes back into the conversation. From there it can leak through later model output or other tool calls. A public URL that redirects to an internal one worked too, because redirects were followed without re-validation.

What does the fix change?
PR #5033 adds a request hook that resolves each request's host and refuses the request if any of its addresses is not globally routable. Because the hook runs before every request, it covers the robots.txt check, the page fetch and every redirect hop. A new --allow-private-ips command-line flag restores the old behavior for local development. It is host-side configuration, so the model calling the tool cannot turn it off.

What does the fix not cover?
The pull request lists two known limits. DNS rebinding remains possible because the hook resolves the name and the HTTP client resolves it again to connect, so a hostile DNS server could answer differently the second time. And names the server cannot resolve are passed through, which matters when a proxy is configured, because the proxy resolves them instead.

What about mcp-server-everything?
NVD's record names mcp-server-everything as well as mcp-server-fetch. The everything server is a test and demo server, and a separate pull request to block SSRF in one of its resource features was still open on October 5. If you run it anywhere other than a developer sandbox, treat it the same way.

How does Anomity help with this?
The Anomity Endpoint Sensor inventories MCP servers configured on every managed endpoint, with versions, so you can find each client that launches mcp-server-fetch and plan the upgrade when a fixed release ships. On agents that expose a pre-execution hook, such as Claude Code PreToolUse, Anomity can allow, deny or log a fetch tool call before it runs, and decisions land in a 90-day audit trail that routes to SIEM, Slack, email or Jira.

## Related

[Insights ### Claude Code Managed Settings Skipped by a Stored API Key - CVE-2026-103012 CVE-2026-103012: a stored API key could make Claude Code skip your org's server-managed policy. Fixed in 2.1.260, plus the 2.1.285-2.1.289 deny-rule fixes. Anomity Research · Oct 5, 2026 · 5 min](https://anomity.ai/blog/claude-code-managed-settings-bypass-cve-2026-103012/)

[Insights ### Claude Fable 5.1 and Mythos 5.1: One Model, Two Safeguard Tiers, and a Fallback Your Security Team Will Hit Fable 5.1 and Mythos 5.1 are one model with two safeguard tiers. Flagged cyber requests in Claude Code fall back to Opus 4.8. What it means for you. Anomity Research · Oct 2, 2026 · 5 min](https://anomity.ai/blog/claude-fable-5-1-mythos-5-1-model-fallback-governance/)

[Insights ### NVIDIA's Open Agent Safety Platform Puts Controls Outside the Agent. Now Count the Agents Outside It. OpenShell sandboxes agents with policy outside their reach, and Sentry watches from the DPU. Both cover the agents you enroll. The rest need a list first. Anomity Research · Oct 2, 2026 · 6 min](https://anomity.ai/blog/nvidia-open-agent-safety-platform-openshell-sentry/)

## Structured data

```json
{
  "@context": "https://schema.org",
  "@type": "BlogPosting",
  "headline": "MCP Fetch Server SSRF - CVE-2026-104120: Fix Merged, No Release Yet",
  "description": "CVE-2026-104120: the reference MCP fetch server can be steered to localhost and cloud metadata. A fix merged Oct 5 on v2/main; PyPI 2026.8.18 lacks it.",
  "datePublished": "2026-10-05",
  "dateModified": "2026-10-05",
  "author": {
    "@type": "Person",
    "name": "Anomity Research",
    "jobTitle": "Anomity Research"
  },
  "publisher": {
    "@type": "Organization",
    "name": "Anomity",
    "url": "https://anomity.ai/",
    "sameAs": [
      "https://www.linkedin.com/company/anomity",
      "https://github.com/Anomity-ai",
      "https://www.wikidata.org/wiki/Q140763940"
    ],
    "logo": {
      "@type": "ImageObject",
      "url": "https://anomity.ai/anomity-logo.png"
    }
  },
  "mainEntityOfPage": {
    "@type": "WebPage",
    "@id": "https://anomity.ai/blog/mcp-server-fetch-ssrf-cve-2026-104120/"
  },
  "image": {
    "@type": "ImageObject",
    "url": "https://anomity.ai/assets/blog/covers/prompt-injection.jpg",
    "width": 1200,
    "height": 630
  },
  "articleSection": "Insights",
  "url": "https://anomity.ai/blog/mcp-server-fetch-ssrf-cve-2026-104120/"
}
```

```json
{
  "@context": "https://schema.org",
  "@type": "FAQPage",
  "mainEntity": [
    {
      "@type": "Question",
      "name": "Am I affected by CVE-2026-104120?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "If an MCP client on a machine or server launches mcp-server-fetch, assume yes until a release containing PR #5033 ships. NVD lists versions up to 2026.6.4, but the fix was merged only on October 5, 2026, and the latest version on PyPI on that date was 2026.8.18, published August 18. The exposure that matters most is where the fetch server runs: on a laptop it can reach local services, and on a cloud host it can reach the instance metadata endpoint."
      }
    },
    {
      "@type": "Question",
      "name": "Is this a new bug?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "Not entirely. The fetch server's README carries a caution that it can access local and internal IP addresses and may represent a security risk. What changed is that the behavior now has a CVE, a public write-up and a merged fix. The reporter says private reports were submitted on June 5, 2026 and posted the write-ups publicly on the project's issue tracker on September 4."
      }
    },
    {
      "@type": "Question",
      "name": "How does prompt injection turn into SSRF here?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "The fetch tool's URL argument is chosen by the model. If the agent reads a web page, issue or document containing instructions to fetch an internal address, the model can call the fetch tool with that address and the response comes back into the conversation. From there it can leak through later model output or other tool calls. A public URL that redirects to an internal one worked too, because redirects were followed without re-validation."
      }
    },
    {
      "@type": "Question",
      "name": "What does the fix change?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "PR #5033 adds a request hook that resolves each request's host and refuses the request if any of its addresses is not globally routable. Because the hook runs before every request, it covers the robots.txt check, the page fetch and every redirect hop. A new --allow-private-ips command-line flag restores the old behavior for local development. It is host-side configuration, so the model calling the tool cannot turn it off."
      }
    },
    {
      "@type": "Question",
      "name": "What does the fix not cover?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "The pull request lists two known limits. DNS rebinding remains possible because the hook resolves the name and the HTTP client resolves it again to connect, so a hostile DNS server could answer differently the second time. And names the server cannot resolve are passed through, which matters when a proxy is configured, because the proxy resolves them instead."
      }
    },
    {
      "@type": "Question",
      "name": "What about mcp-server-everything?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "NVD's record names mcp-server-everything as well as mcp-server-fetch. The everything server is a test and demo server, and a separate pull request to block SSRF in one of its resource features was still open on October 5. If you run it anywhere other than a developer sandbox, treat it the same way."
      }
    },
    {
      "@type": "Question",
      "name": "How does Anomity help with this?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "The Anomity Endpoint Sensor inventories MCP servers configured on every managed endpoint, with versions, so you can find each client that launches mcp-server-fetch and plan the upgrade when a fixed release ships. On agents that expose a pre-execution hook, such as Claude Code PreToolUse, Anomity can allow, deny or log a fetch tool call before it runs, and decisions land in a 90-day audit trail that routes to SIEM, Slack, email or Jira."
      }
    }
  ]
}
```

```json
{
  "@context": "https://schema.org",
  "@type": "BreadcrumbList",
  "itemListElement": [
    {
      "@type": "ListItem",
      "position": 1,
      "name": "Home",
      "item": "https://anomity.ai/"
    },
    {
      "@type": "ListItem",
      "position": 2,
      "name": "Blog",
      "item": "https://anomity.ai/blog/"
    },
    {
      "@type": "ListItem",
      "position": 3,
      "name": "MCP Fetch Server SSRF - CVE-2026-104120: Fix Merged, No Release Yet",
      "item": "https://anomity.ai/blog/mcp-server-fetch-ssrf-cve-2026-104120/"
    }
  ]
}
```
