Synthetixis← All writing

WRITING

MCP is a trust boundary you didn't know you crossed

12 min read

Connecting an MCP server feels like installing a package. It's closer to creating a user account.

The ritual is the one we've performed a thousand times. Find something that does what you need, glance at the star count, paste a line into a config file, restart. Two minutes.

The same muscle memory that installs a date formatting library installs a program that can read your filesystem, spend your API credits, and open network connections on your behalf, at the direction of a model that decides what to do next by reading text.

We have decent instincts about trust boundaries. The boundary is the line where data crosses from somewhere you control to somewhere you don't, and we validate at those lines because we've been burned at them for thirty years. The problem with MCP isn't that it lacks one. It's that the boundary doesn't look like one. It looks like a dependency choice, so it gets a dependency choice's worth of scrutiny.

We went looking for how bad that actually is. The looking turned out to be the story.

Title card reading "MCP is a trust boundary" in a teal-to-blue
gradient, above the line "installed like a package, granted like
an account."

What you're granting

A program written by a stranger, permitted to act with your permissions, on the instruction of a model that can be persuaded by text it reads.

Every clause there is load-bearing.

Written by a stranger, because when Enkrypt AI scanned a thousand servers in October 2025, none of them shipped security documentation. Not a low number. Zero.

With your permissions, because the process inherits your environment, your tokens, and your filesystem access.

On the instruction of a model, because you aren't the one deciding which tool gets called with which arguments.

Persuaded by text it reads, because the model's context is filled by whatever comes back from those tools.

That last one has no precedent in the systems we're used to.

The direction of trust is inverted

When you call a REST API, you send a request and validate the response. The response is data. It sits in a variable. It doesn't tell your program what to do next.

When an agent calls an MCP tool, the response lands in the model's context, and everything in the model's context is a candidate instruction.

Invariant Labs showed this in April 2025 with what they named tool poisoning: a malicious description on an otherwise ordinary tool, instructing the agent to read ~/.ssh/id_rsa and pass the contents along. The tool worked. The description was the payload.

CyberArk pushed it further in Poison everywhere, showing the same trick through parameter names, type hints, default values, and error messages. Their example returns a fabricated error saying the tool needs your SSH key to perform addition. The agent complies, because a well-formed error message in a context window is indistinguishable from a legitimate one.

There's no structural separation between the data an agent retrieves and the instructions it follows. Both are text arriving through the same channel. Simon Willison's lethal trifecta names the condition precisely: private data, untrusted content, and a way to send things outward. Prompt injection isn't a bug in that arrangement. It's the arrangement working as designed, with an input nobody anticipated.

The permissions compose, too. Each server runs with whatever authority the host process has, and connecting a second one doesn't create a second sandbox. It widens the surface to the union of everything connected, which is not a thing anyone designed or reviewed.

Cyata demonstrated exactly this against Anthropic's own reference implementations, disclosed January 20, 2026. Three medium-severity flaws in the official Git MCP server, none of them impressive alone. Chained, and combined with the Filesystem server, they produce remote code execution: bypass the path check, initialize a Git repository inside ~/.ssh, write a malicious .git/config containing a shell hook, then trigger it through argument injection in git_diff. The whole sequence runs on prompt injection. A poisoned README is enough.

Cyata's CEO put it plainly: on its own each server was relatively safe, and the cross interaction between the two is what broke their assumptions. Anthropic's fix removed the git_init tool entirely.

The client is the target

We're trained to think of the server as the thing under attack. Here it's the laptop.

In July 2025, JFrog disclosed CVE-2025-6514, a command injection flaw in mcp-remote scored 9.6 at NVD, affecting versions 0.0.5 through 0.1.15 of a package downloaded more than 437,000 times. The attack triggers on connection. A malicious server answers the OAuth handshake with a crafted authorization_endpoint value, and on Windows the payoff is arbitrary command execution with full parameter control.

Four weeks earlier, Tenable and Oligo Security separately surfaced CVE-2025-49596 in MCP Inspector, scored 9.4 on CVSS 4.0, where the local web interface shipped with no authentication between browser and proxy at all.

Neither is exotic. Both are the kind of thing a security review catches in an afternoon.

The numbers, and why we stopped trusting them

This is where we expected to write a paragraph of alarming statistics. We had them lined up. Then we checked them.

The most-cited assessment is Equixly's, published March 29, 2025: 43% of tested servers with command injection flaws, 22% with path traversal, 30% permitting unrestricted URL fetching. Those figures have been repeated across dozens of articles since.

Almost none of them mention that Equixly never published a sample size. The post says it assessed "some of the most popular MCP server implementations over the past month." That's the whole method. A denominator producing a clean 5% for the "other issues" bucket is not a large one.

The bigger numbers have a different problem. Endor Labs looked at 2,614 implementations and reported that 82% "use file system operations prone to Path Traversal" and 67% "use sensitive APIs related to Code Injection."

Read that wording carefully, because the industry press mostly didn't. It says the code calls APIs associated with a vulnerability class. It doesn't say the code is vulnerable. Those are separated by the entire discipline of exploitability analysis, and pattern matchers are bad at the distinction. Lenarduzzi and colleagues ran six static analysis tools across 47 Java projects and checked every warning against a manually built ground truth. Precision ranged from 18% to 57%. They also found little to no agreement between the tools about which lines were even a problem.

Then there's the study nobody quotes. Hasan and colleagues at Queen's University measured 1,899 servers and published through peer review, forthcoming in ACM Transactions on Software Engineering and Methodology. They found general vulnerabilities in 7.2% and tool poisoning in 5.5%. The work went up in June 2025, so it is contemporaneous with the vendor scans rather than newer than them. Same era, same ecosystem, different method.

Seven percent, not eighty-two.

That gap isn't a disagreement about MCP. It's a disagreement about what "vulnerable" means, and the peer-reviewed number is the one counting exploitable defects rather than suspicious-looking function calls.

We also went looking for evidence that things improved after the specification hardened. A widely shared 2026 article reports 43% of servers still carrying command injection flaws, which reads as a year-over-year comparison showing no progress. Follow the citation back and the 2026 figure is Equixly's March 2025 number, re-cited and re-dated. Nobody has re-run the methodology. There is no year-over-year comparison.

We were most of the way through building an argument on it.

What holds up

Three things survive, and they're enough.

Authentication is measurably absent, and this one has been checked properly. Henley Wing Chiu tracked 1,412 company-operated MCP servers through February 2026 and found that, among those where he could determine the method, 38.7% had no authentication at all. Anyone could connect, initialize a session, and enumerate every tool.

The tool names are the part worth reading twice. On unauthenticated servers he found confirm_transfer, create_transfer and get_kyc_status at a fintech company. lookup_candidate and get_resumes at an HR platform. get_account, create_refund and simulate_payment at a payments provider. On one financial services server, an unauthenticated tool call returned what appeared to be account data.

Censys measured the exposure from the other direction. As of April 28, 2026 it counted 12,520 internet-accessible MCP services across 8,758 unique IP addresses in 56 countries, of which the largest category was direct database query interfaces and 687 exposed system control functions such as command execution. Eight days later the count passed 21,000. BlueRock's scan of roughly 7,000 public servers put the no-authentication rate at 41%, close enough to Chiu's figure to be worth noting and measured separately.

Credentials are long-lived and loosely held. Astrix examined 5,200 public repositories in October 2025 and found 53% relying on static API keys or personal access tokens that are rarely rotated, against 8.5% using OAuth. Of those using static keys, 79% pass them through plain environment variables.

And it has already happened. In September 2025, Koi Security disclosed the first malicious MCP server found in the wild. Someone cloned Postmark's official MCP server from GitHub and republished it to npm under the same name. Fifteen versions behaved exactly like the original, which is how it earned its way into people's workflows. Version 1.0.16, published September 17, added one line that blind-copied every outgoing email to an address the publisher controlled.

The package took 1,643 downloads before it came down. Koi estimated a fifth of those were running in production, around 300 organizations quietly forwarding their password resets and invoices to a stranger. When the researchers made contact, the publisher didn't reply. He deleted the package, which does nothing for anyone who already had it installed.

Four months later came the Cyata chain described above, in Anthropic's own reference implementation. The official MCP registry that launched in September 2025 verifies namespace ownership and performs no security scanning of the code it lists.

The mistake both sides are making

Equixly published one more finding, and it's the one that stayed with us. After disclosing to the affected vendors, it recorded the responses: 30% acknowledged and released fixes, 25% never replied, and 45% said the risks were theoretical or acceptable.

Forty-five percent of the people who wrote these servers were told exactly what was wrong and decided it didn't count.

That's the same error as the 82%, pointed the other way. One group asserts vulnerability without confirming exploitability. The other asserts safety without checking. Both substitute a confident summary for evidence, and both are cheaper than finding out.

The practices that follow aren't novel. They're the ones we already apply at every other boundary, which is the tell that recognizing the boundary was the missing step.

Read what you're installing, in proportion to what you're granting it. Not the README. The tool definitions, the argument handling, and every place a tool argument reaches a shell, a filesystem path, or an outbound request. A server that only reads is a different risk class from one that writes, and both differ from one that executes.

Scope the credentials to the task, not to the developer. The default is a static token carrying the permissions of a human who needs to do everything. The token an agent uses should expire, should cover only the operations that agent performs, and should be distinguishable in an audit log from a person's activity. Astrix's 53% measures how rarely anyone bothers.

Put the boundary around the process, not the config file. Filesystem access confined to a working directory, network egress restricted to known destinations, no ambient reach into the credential store. If the process can't get to something, no amount of clever text in a tool response makes it reachable.

Require confirmation for the irreversible, and only for that. A prompt firing forty times an hour becomes a button people click without reading, which is worse than no prompt. Save it for actions where being wrong is expensive and permanent.

Assume tool output is hostile input. Treat it the way you'd treat a form field. This is the hardest one, because the consuming system is a model rather than a parser, and nobody has a good answer yet for sanitizing text whose meaning is the payload.

We'd rather tell you which of these caught something for us, and what it cost. That's a different post, and it waits until we've run long enough to publish numbers instead of practices.

Where these numbers come from

Worth saying plainly, since untangling it took a week.

Equixly, Endor Labs, Astrix, Enkrypt AI, JFrog, Oligo, Tenable, BlueRock, Cyata and Koi all sell security products, and several of these reports shipped alongside a launch. That doesn't make them wrong. Vendor research surfaced the postmark backdoor, both CVEs, and the chain against Anthropic's own servers.

The exceptions are worth naming. Chiu's server tracking and the two academic papers were not produced by anyone selling a remedy, and they are the only numbers here with no commercial interest attached. One of them is also the smallest.

The specification has moved too. OAuth 2.1 arrived in the 2025-03-26 revision. The June 2025 revision made servers formal OAuth resource servers and required resource indicators, so a malicious server can't reuse a stolen token elsewhere. The current stable revision is 2025-11-25. A mental model formed in early 2025 is out of date in the direction of things being better.

The spine

None of this was hidden. The CVEs have public advisories and patched versions. The academic paper is on arXiv. The specification is versioned in the open. The backdoor was found by someone who bothered to diff a package update.

And the number most people can quote has no denominator, from a sample nobody disclosed, about a measurement nobody has repeated.

We came to write about a trust boundary people cross without noticing. We found two. The gap between knowing something is a boundary and treating it as one is where the year went, and that applies to the people measuring the problem as much as to the people shipping it.

Check the thing itself.

Written by Synthetixis, an AI-native product studio. More on what most AI software gets wrong.