A repo's .git/config could run programs through MCP's git server: 6 fixes in v2.4.0 and 4 checks for your configs
The reference MCP servers most of us bolt into a client config without a second thought shipped six security fixes on November 11. Three servers are affected: the filesystem server, the git server and the fetch server. O
The reference MCP servers most of us bolt into a client config without a second thought shipped six security fixes on November 11. Three servers are affected: the filesystem server, the git server and the fetch server. One of the six is rated high, and it sits in the git server: a read-only status call against a repository you did not write could run a program named in that repository's own .git/config, with the privileges of the server process.
I wrote about the previous security release when it landed on October 25 with eight fixes. Two security releases in under three weeks on the same set of servers says something about how much scrutiny these tools get now, and how much of an agent's real attack surface lives in the server processes you configure, not in the model. The full details are in the v2.4.0 release notes.
What shipped, and who is exposed
Six advisories across three packages, all published November 11:
| Package | Affected | Fixed in |
|---|---|---|
@modelcontextprotocol/server-filesystem |
all versions before 2.3.0, and date versions 2025.1.14 through 2026.8.31 | 2.3.0 |
mcp-server-git |
through 2026.11.4 | 2026.11.11 |
mcp-server-fetch |
through 2026.11.4 | 2026.11.11 |
The exposure test is simple: if any client config on your machine references one of these three packages, and the version that actually runs is in the affected range, you are exposed. In practice that means a config or lockfile pinned to a date version, a Docker image pulled months ago, or a wrapper script that never gets updated. A bare npx -y entry with no version resolves the latest release on each launch, so it picks up the fix, at the usual price of running whatever ships next.
The high one: a repo's own config could run programs
GHSA-6hqx-gqrx-c5r2, rated high. The mechanism is uncomfortable because it hides behind a read-only tool. mcp-server-git shells out to git, and git reads the repository's .git/config before doing anything. Several keys there name programs to run: core.fsmonitor, diff.external, hooks, filter and merge drivers, signing. On the old server, a call such as git_status against an untrusted repository honored those settings, so cloning a repo you found and asking the agent for a status could execute a program the repository's author chose, with the server's privileges.
The fix overrides those settings on every git command the server runs, and refuses git versions older than 2.31, because those ignore the overrides. That refusal is a behavior change to know about: an environment with an old git now gets a hard error rather than silently losing the protection.
The git confinement follow-up
The second git advisory, GHSA-q74p-4wrc-q7w6, rated medium, completes a fix from October 28. When you start the server with --repository, that boundary could be escaped three ways: a repository nested inside the allowed one reading another repository's objects through objects/info/alternates, a linked worktree's Git directory passed off as the allowed repository's, and a symlink inside a Git directory leading outside. All three are refused now. On Windows, a directory junction is not covered yet, tracked as issue #5520.
Filesystem: reads could leave the directories you allowed
Two medium advisories here. The first is a check-to-use race: if an allowed directory is swapped for a symlink between the access check and the read, the read tools could return a file from outside the allowed directories. Reads now open the file relative to the directory that was checked, which writes already did, and FIFOs, sockets and devices are refused outright. It is closed on Linux and macOS. On Windows the release notes are blunt: the change "narrows the race without closing it".
The second, GHSA-7m4x-rv66-mxhh, is the same class in move_file. A same-device move first takes the source out of its own checked directory under a fresh name, so a source directory swapped for a symlink can no longer pull an outside file into the allowed directories, where it would become readable.
Fetch: two small guard gaps
The fetch server's private-address guard read the deprecated IPv6 site-local range fec0::/10 as public. It is refused now, along with any IPv6 address outside global unicast space (2000::/3) that does not carry an IPv4 address. Separately, robots.txt rules are matched against the path the site will resolve, not just the path as written, so //private or /x/../private no longer gets past Disallow: /private. Both are rated low. Cheap fixes, worth having if your agent fetches URLs from anywhere you do not control.
The npm trap that keeps you on the vulnerable version
This is the part I expect to bite people. The TypeScript servers moved from date versions (2025.x, 2026.x) to semantic versions in 1.0.0. Package managers rank 2.3.0 below every 2025.x and 2026.x version, so a lockfile or pin on a date version will never be offered 2.3.0 as an upgrade. To the resolver it looks like a downgrade. The release notes say it directly: install it explicitly.
npm install @modelcontextprotocol/[email protected]
For the Python servers, pin the same way, mcp-server-git==2026.11.11 and mcp-server-fetch==2026.11.11 in whatever launches them.
This is the same lesson as Claude Code's new engines version-range field and the MCP Inspector OAuth issue: version plumbing decides your exposure as much as the code does, and the interesting failures happen where two versioning schemes meet.
Four checks I would run today
First, find every config that references the three packages:
grep -rn "server-filesystem\|mcp-server-git\|mcp-server-fetch" \
~/.claude.json ~/.claude/ ~/.cursor/ ~/.codex/ ~/.config/ 2>/dev/null
Second, replace bare or stale entries with explicit pins to the fixed versions, so the resolver has no say in the matter:
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/[email protected]", "/srv/data"]
},
"git": {
"command": "uvx",
"args": ["--from", "mcp-server-git==2026.11.11", "mcp-server-git", "--repository", "/srv/repo"]
}
}
}
Third, Docker users: every server image now runs as its non-root user. A volume owned by root can stop working after the upgrade, and the memory server README gained upgrade steps for exactly that case.
Fourth, if anything reaches the everything server from another machine, know that its HTTP transports now bind to loopback by default and need HOST set to widen. A setup that silently stops connecting after this upgrade is probably hitting that line.
What is still open after the update
Windows carries two known gaps: the filesystem read race is narrowed, not closed, and git directory junctions are not covered. The git server refuses git older than 2.31 instead of running unprotected, which surfaces old toolchains as errors. None of the six has a CVE id at the time of writing, they are tracked as GitHub security advisories, which matters if your scanner alerts on CVEs only.
Two smaller changes deserve a look while you are in there. The filesystem server gained --read-only-dir for per-directory read-only access, which is the clean way to give an agent docs it cannot touch. And the fetch server caps response body size while reading, so one giant response no longer blows up memory.
If your agents open repositories or directories you did not create, the git fix is the one to act on today. The rest can ride your normal upgrade path, as long as that path actually reaches the fixed versions, and for the filesystem server this release means it will not do that on its own.
Originally published by Dev.to Security. Aggregated on AIWithGhost for educational purposes β full credit and traffic to the original publisher.