Skip to content
System nominalUTC --:--:--Articles 080
Security 5 min read

An SSRF in the Official MCP Fetch Servers

CWE-918 in mcp-server-fetch and mcp-server-everything 2026.6.0 to 2026.6.4 lets a crafted URL steer the fetch tool, and the fix pull request is still unmerged.

Cover graphic for: An SSRF in the Official MCP Fetch Servers

Every version of the reference MCP fetch servers from 2026.6.0 through 2026.6.4 carries a server-side request forgery in the tool whose entire job is to fetch a URL, and there is no patched release to move to. The CVE-2026-104120 record was published on 2 October 2026 and updated on 6 October. It states that the pull request which fixes the issue awaits acceptance, and that the exploit has been disclosed publicly and may be used. Until that pull request lands in a release, the only available move is to reduce what the server can reach.

What the flaw is

The vulnerability is CWE-918, server-side request forgery, in the function fetch_url of mcp_server_fetch/server.py, in the Fetch Tool component of modelcontextprotocol mcp-server-fetch and mcp-server-everything. The affected versions are 2026.6.0, 2026.6.1, 2026.6.2, 2026.6.3 and 2026.6.4, inclusive.

The trigger is manipulation of the url or path argument. The record describes the attack as remotely initiated, with no privileges required and no user interaction. That combination is the reason the flaw matters more than its impact ratings suggest on their own: an attacker does not need an account on the host running the server, and does not need anyone to click anything.

What SSRF buys an attacker in this position is reach. The request is issued by the process running the MCP server, not by whoever supplied the URL. Anything that process can route to, including services bound to loopback or to a private network segment that the attacker cannot address directly, becomes reachable through it. The fetch tool is a fetch tool; it is not, by design, a general-purpose network client with a destination policy.

What the record does not claim matters too. CISA's SSVC assessment records the technical impact as partial, and the CVSS 3.1 vector rates confidentiality, integrity and availability impact as low individually. This is not a remote code execution bug. It is a bug that turns an already-trusted agent component into a request forwarder, which in an agent stack is usually enough.

Two severity bands for one bug

The same record carries a high score and a medium score, from different versions of the scoring system, and reporting only one of them is how a security team ends up arguing about the wrong number.

On CVSS 3.1 the score is 7.3, High, with the vector AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:L. CVSS 3.0 produces the same 7.3. On CVSS 4.0 the CNA, VulDB, scores it 6.9, Medium, and NVD's later 4.0 entry scores it 5.5, also Medium. The older CVSS 2.0 score is 7.5. Two vendors of the same record land a full severity band apart depending on which version of the standard they ran.

The other signals are similarly split. The record's EPSS score is 0.00288, at the 19.99th percentile, as of 16 October, which is a low predicted probability of exploitation in the next thirty days. CISA's assessment records exploitation as PoC, automatable as yes, and technical impact as partial. A public proof of concept plus an automatable trigger is a different risk picture from a low EPSS percentile, and a severity label alone does not distinguish the two.

CVE-2026-104120
  CWE              918 (server-side request forgery)
  affected          mcp-server-fetch, mcp-server-everything 2026.6.0 - 2026.6.4
  published         2026-10-02 02:15 UTC
  updated           2026-10-06 02:27 UTC
  CVSS 3.1          7.3 High
  CVSS 3.0          7.3 High
  CVSS 4.0          6.9 Medium (VulDB, CNA) / 5.5 Medium (NVD)
  CVSS 2.0          7.5
  SSVC              exploitation PoC, automatable yes, technical impact partial
  EPSS              0.00288 (19.99th percentile) as of 2026-10-16
  fix               PR awaits acceptance as of the 2026-10-06 update

The fix is proposed, not merged

The record references a GitHub issue, 4492, tagged as an exploit, and a pull request, 4890, tagged as a patch. As of the 6 October update, the pull request had not been accepted. That is the status line a reader should carry away, because it removes the usual first instruction from a vulnerability write-up. There is no fixed version to pin to, and no advisory telling you which release closes it.

The record also credits the reporter as geochen, a VulDB user, with VulDB as the assigning CNA. VulDB's CNA scorecard grade in the CVE record is B, 82.27 out of 100 across 3,870 records in the preceding 180 days, which is context on the record's completeness rather than on the bug.

Anyone depending on these servers should watch pull request 4890 and the issue thread directly. A merged pull request is not a released version either, so the check has two steps: has the fix been accepted, and has it shipped in a version you can install.

Why an SSRF in a fetch tool matters to an agent stack

These are the reference servers that people drop into agent stacks, and the fetch server is the one whose designed behaviour is to retrieve a URL on request. That design is the vulnerability class waiting to happen. A tool that fetches whatever it is told to fetch will fetch whatever it is told to fetch, and in an agent deployment the thing doing the telling may be a model responding to content it read somewhere else.

The path from a prompt injection to an internal network request runs through exactly this kind of component. A page, a document or a tool result tells the model to fetch something. The model calls the fetch tool. The MCP server makes the request from inside your network, where the address it just requested is reachable and the attacker is not. Nothing in that chain requires the attacker to have a foothold.

The compensating detail is the partial technical impact. A single SSRF in a fetch tool does not hand over the host. It reads what an internal endpoint will serve to an unauthenticated client, and on a network with unauthenticated metadata services, internal dashboards or a service mesh with permissive routing, that is often more than it sounds.

What to do when there is no patched version

Start by finding out whether you run the affected versions. The pin is usually in a requirements file, a lockfile or a container definition rather than in application code.

grep -rn -E "mcp-server-fetch|mcp-server-everything" \
  requirements*.txt pyproject.toml uv.lock poetry.lock package.json 2>/dev/null

If the fetch server is not needed, remove it. That is the only remediation with no residual risk, and reference servers accumulate in stacks long after the experiment that justified them.

If you do need it, treat every URL that reaches it as untrusted input, because it is. Restrict egress from the host or container running the MCP server to the destinations the tool legitimately needs, and deny requests to loopback, link-local and private address ranges at the network layer rather than in the tool. The tool's own argument handling is the thing under repair, so a control that depends on the tool inspecting its own input is not a control you can rely on today.

Watch the host's outbound traffic for requests to internal addresses that have no business receiving them, and for metadata service endpoints in particular. Log the resolved destination of each fetch rather than only the URL that was requested, since a name that looks external can resolve to an internal address.

Then track the pull request and the issue. When a release closes the bug, upgrade and retest, and check whether the fix validates the destination or only the URL string. A fix that rejects a literal 127.0.0.1 and allows a hostname that resolves to it is not a fix.

Primary sources

More from the wire