↓ Skip to main content
  1. Tech Blog: AI, Security, Infrastructure & Open Source/

MCP Security Fixes — Why Your Package Manager May Miss Them

Osmond van Hemert
Author
Osmond van Hemert
Developer Tooling - This article is part of a series.
Part : This Article

A security update can be available without looking like an upgrade. That is the trap in the MCP reference servers’ October 25 release: the fixed npm packages are numbered 2.0.1, while older installations can carry versions beginning with 2025 or 2026. Normal version ordering puts those date-based releases above the fix.

The project’s v2.1.0 release notes describe eight vulnerabilities across the filesystem, everything and fetch servers, and explicitly warn that package managers will not offer the semantic-versioned npm fix as an upgrade from date versions. If you operate these tools, a quiet dependency dashboard is not evidence that the running server is patched.

The practical job is to identify the package your client actually launches, select its fixed version explicitly, and check the remaining platform limitations. This is not another MCP protocol migration like the July stateless specification overhaul. It is maintenance of the implementations that turn a model’s requests into filesystem operations and network traffic.

One Repository Release, Three Package Versions
#

v2.1.0 is the repository release, not the version to install for every server. Its package table maps the fixes as follows:

PackageFixed Package VersionFixes in This Release
@modelcontextprotocol/server-filesystem2.0.1Four filesystem boundary issues
@modelcontextprotocol/server-everything2.0.1Cross-origin access through HTTP/SSE transports
mcp-server-fetch2026.10.24Three fetch-policy issues

The release lists filesystem versions 1.0.0 through 2.0.0, plus date versions through 2026.8.31, as affected. For everything, its table lists 1.0.0 through 2.0.0 and date versions from 2025.9.24 through 2026.8.31; the advisory also discusses an earlier transport exposure. Fetch releases through 2026.10.19 need updating. The memory, sequential-thinking, git and time packages are unchanged in this release.

That split matters when someone writes “upgrade MCP to 2.1.0” in a ticket. It leaves the operator guessing which artifact to replace and what version should appear afterward. Record the package name and expected installed version, not just the repository tag.

What the Fixes Actually Protect
#

These are different boundary failures with different prerequisites, not eight interchangeable remote-code-execution bugs.

Filesystem: The Checked Path Must Be the Used Path
#

The filesystem fixes cover a parent-directory race, inconsistencies in handling trailing quotes or whitespace, a differently cased symlink bypass on case-insensitive volumes, and metadata access through symlinks in list_directory_with_sizes.

The parent-directory race advisory illustrates the central problem: checking that a parent directory is allowed does not help if another local process can replace it with a symlink before the write happens. An operation that passed validation can then land outside the allowed tree. That concurrent local manipulation is an important prerequisite; merely receiving an arbitrary remote request is not the whole attack.

On Linux and macOS, the advisory says 2.0.1 anchors writes to the validated directory. On Windows, the fix is only partial. Swapping a directory for a junction between validation and use can still redirect writes, directory creation and move destinations outside the allowed directories.

The maintainers’ Windows guidance is specific: do not configure an allowed directory that another user or an untrusted local process can write to. Treat that as a deployment constraint after upgrading, not a reason to keep an older version. Do not describe 2.0.1 as a complete Windows containment fix.

Everything: Local HTTP Is Still a Browser-Reachable Surface
#

The everything-server advisory describes permissive cross-origin access to its HTTP/SSE transports. A page visited in a developer’s browser could invoke get-env and read the server process’s environment, including whatever credentials that process inherited.

The release adds Origin checks and removes wildcard CORS. The advisory explicitly says the default stdio transport is not affected by this HTTP exposure. It also says releases before 2025.9.24, although lacking the permissive CORS headers, remained exposed to DNS rebinding because they checked neither Origin nor Host; its recommendation is to upgrade those earlier versions too.

I would also remove unnecessary secrets from the server’s environment. That is additional damage limitation, not a substitute for the update. As the earlier AI browser-agent hijack analysis showed in a different setting, “local tool” and “isolated from web content” are not equivalent promises.

Fetch: Check the Destination You Will Actually Reach
#

Two fetch fixes address server-side request forgery safeguards. The IDNA hostname advisory describes the validator and HTTP client resolving different representations of an internationalized hostname: the check could approve a public destination while the connection reached an internal one.

The NAT64 advisory covers IPv6 addresses in 64:ff9b::/96 carrying a non-public IPv4 destination. Exploitability depends on the host having suitable NAT64 egress; it is not evidence that every deployment can reach a metadata endpoint through that route.

The third issue is separate: robots.txt checks were not repeated after redirects. The fix reapplies that fetching policy at each hop. Do not confuse respecting robots.txt with authentication or protection against internal-network access.

Even after updating, the fetch README documents remaining guard limitations, including DNS rebinding between validation and connection and names only a proxy can resolve. Its --allow-private-ips option disables the private-address guard. I would keep that option out of an untrusted-web workflow and enforce independent egress restrictions where internal services must remain unreachable.

Upgrade the Installation Your Client Uses
#

Start with the MCP client’s launch configuration. Is it executing a project dependency, an npx package, a Python environment, a container image or a bundled extension? Updating a package in your current terminal does not establish that the client uses it.

For a project that already manages the affected npm servers as dependencies, select the fix explicitly. Run only the commands for servers you actually use, in the project that owns those dependencies:

npm install --save-exact @modelcontextprotocol/[email protected]
npm install --save-exact @modelcontextprotocol/[email protected]

Then inspect that project’s installed dependency tree:

npm ls @modelcontextprotocol/server-filesystem @modelcontextprotocol/server-everything

For an npx launch configuration, update the package argument itself—for example, @modelcontextprotocol/[email protected]—rather than assuming a nearby project’s installation controls the launch. Check compatibility too: the filesystem server’s release-specific README requires Node.js 24 or later for npx or source execution.

For a pip-managed fetch installation, use the interpreter belonging to the server’s environment:

python -m pip install --upgrade "mcp-server-fetch==2026.10.24"
python -m pip show mcp-server-fetch

That does not update a separate environment managed by uvx, a container or a desktop extension. For those, change the actual launch specification or obtain a patched artifact, then verify its contents. These examples select the versions fixed in the October 25 release; check current advisories before treating any pin as a permanent policy.

Close the Rollout With Evidence
#

I would consider the rollout complete only after checking four things:

  1. Launch identity: the client configuration points to the intended executable, environment or image, with no stale alternate registration.
  2. Installed artifact: package metadata in that location shows the selected fixed version, and any checked-in dependency declarations and lockfiles reflect the change.
  3. Process replacement: restart the server or its owning client, then inspect launch diagnostics to confirm the new artifact—not an already-running old process—is being used.
  4. Behavior and limits: smoke-test ordinary tool operations in a disposable workspace, review allowed directories and inherited credentials, and document any Windows or network restrictions that still apply.

This is the same operational distinction as replacing every serving PHP runtime during PHP2Shell patching: obtaining a fixed artifact and proving the old process stopped serving requests are separate tasks.

A patch also does not prove that an earlier deployment was never abused. If your review finds suspicious tool calls, unexpected file changes or credential access, handle that through incident response rather than closing the investigation on the strength of a version number. Conversely, exposure alone is not proof of compromise.

My Take
#

The uncomfortable part of this release is not just the bugs. It is that the normal maintenance signal can point in the wrong direction: the security fix is numerically older than the package you already have. I would want an explicit migration check for date-versioned MCP installations, not another assurance that dependency automation is enabled.

For tools with filesystem and network access, my minimum inventory would include the launcher, resolved artifact, owner and granted permissions. Without those four facts, “we updated the server” is difficult to verify, especially when the desktop client and the shell use different environments.

My expectation is that agent tooling will increasingly need the same rollout discipline as other privileged services. This release is a good reason to establish it now: select the correct package fixes, replace the running processes, and keep the remaining Windows and network limitations visible instead of letting a green update check stand in for a security boundary.

Developer Tooling - This article is part of a series.
Part : This Article

Related