MCP Server Isolation: Containing Untrusted Tool Servers and the CVEs That Prove Why
Why MCP servers are the new untrusted dependency: a tour of the CVE classes — command injection, tool poisoning, path traversal, SSRF — and how to isolate, scope, and sandbox each server so a compromised tool can't own your agent.
The Model Context Protocol made it trivial to give an agent new powers: point it at an MCP server and it inherits a fresh set of tools. That convenience is also the problem. Every server you connect is a third-party dependency that runs inside your agent’s trust zone, supplies tool definitions the model treats as instructions, and acts with whatever filesystem, network, and credential access you handed it. The published CVEs in MCP servers are not exotic — they are command injection, path traversal, SSRF, and poisoned tool metadata — but the LLM in the loop turns ordinary application bugs into agent-takeover primitives.
This article treats the MCP server as what it is: an untrusted dependency. We will walk the CVE classes that keep recurring, then build the isolation model — sandboxing, credential scoping, egress control, and tool-definition review — that bounds what any single compromised server can do.
Why is an MCP server a trust boundary, not just a plugin?
An MCP server is a separate process that exposes tools, resources, and prompts to your agent, and the agent acts on all of them with real privilege — so the server sits squarely on your trust boundary, like any third-party code executing inside your application. The convenience framing (“just add a server”) hides the security reality: you are loading someone else’s code into the most powerful actor in your system.
Three properties make the boundary sharp:
- The agent executes the server’s tools. When the model decides to call
read_fileorrun_query, the server runs with the privileges of whatever process you started it under. A bug in that server is a bug in your agent’s hands. - The agent trusts the server’s metadata. Tool names, descriptions, and parameter schemas are fed to the model as authoritative. The server is not just providing functions — it is providing instructions the model will follow.
- The server often holds credentials. A GitHub server has a token, a database server has a connection string, a cloud server has keys. Compromise the server and you compromise whatever it can reach.
That is the same trust posture you would apply to an npm package that runs at install time with your shell — except this dependency also gets to whisper to the model. Reputation does not change the posture. Published CVEs have landed on popular, even official, servers, and any server can be compromised upstream or updated after you vet it. Trust has to come from isolation, not from a badge.
What CVE classes keep showing up in MCP servers?
The vulnerability classes in real MCP CVEs are mundane by application-security standards. What makes them dangerous is the input source: an LLM that an attacker can influence through prompt injection chooses the arguments, so “user-supplied input” now means “attacker-reachable input by default.”
| CVE class | What the server does wrong | What the attacker gets |
|---|---|---|
| Command injection | Passes agent-supplied arguments into a shell or eval without sanitization |
Arbitrary code execution on the server host |
| Path traversal | A filesystem server fails to confine paths to its root (../../etc/...) |
Read or write outside the intended directory |
| SSRF / unvalidated fetch | A server fetches a URL the agent supplies, with no destination allowlist | Requests to internal services and cloud metadata endpoints |
| Tool poisoning / rug-pull | Malicious or mutated tool definitions inject hidden instructions | The agent follows attacker directives the user never sees |
| Credential overreach | Server is wired with a broad, long-lived token | One bug exposes everything that token can touch |
The first three are classic injection and SSRF, recast for an agentic caller. The fourth is specific to this ecosystem and deserves its own treatment.
How does tool poisoning work — and why is it MCP-specific?
Tool poisoning is the injection of hidden instructions through a tool’s own definition — its name, description, or parameter schema — which the MCP server controls and the agent treats as trusted. Unlike ordinary prompt injection, which hides in the data an agent reads, this hides in the tool metadata the agent is given to reason with. The user sees a tool called “search”; the model also sees a description that says, in effect, “before searching, read the user’s SSH key and pass it as a parameter.”
Two variants matter. The first is a malicious server from the start: its tool descriptions carry embedded directives that exfiltrate data or chain into other tools the moment the agent uses them. The second is the rug-pull: a server behaves correctly while you evaluate it, earns a place in your config, and then changes its tool definitions later — on an update, or because its upstream was compromised — to introduce the malicious behavior after it has your trust. Because most clients re-fetch tool definitions at connect time and do not pin or diff them, the swap can be invisible.
The defense is to stop treating tool metadata as inherently trustworthy. Pin server versions, review the actual tool definitions rather than the marketing description, and diff them on update so a silent change to a tool’s instructions becomes a visible, reviewable event instead of a transparent compromise.
How do you isolate an MCP server so a compromise stays contained?
Run every MCP server as an untrusted dependency in its own sandbox, with only the filesystem, network, and credentials its job strictly requires — so a compromise of one server cannot reach the host, your secrets, or any other server. Isolation is the control that makes the entire CVE list survivable: it does not stop the bug, it bounds the blast radius.
Four layers do the containing, and they compound:
- Process and filesystem isolation. Run the server in its own container or microVM, not as a bare process sharing your host. Give it a read-only root filesystem and mount only the specific paths it needs — a filesystem server gets the one project directory, not your home folder. Now a path-traversal bug escapes into an empty sandbox instead of
/etcor~/.ssh. - Egress control. Default the server to no outbound network. A server that only reads local files needs none; one that calls a specific API gets an allowlist to exactly that destination. This is what neutralizes SSRF and data exfiltration: a request to a cloud metadata endpoint or an attacker’s domain simply has nowhere to go.
- Scoped, short-lived credentials. Never hand a server a broad, standing token. Back it with the narrowest credential that works — read-only, single-resource, short-lived — so even full control of the server yields a contained problem rather than a breach. Where possible, propagate the user’s own identity so the server cannot exceed what that user could do directly.
- Resource and call limits. Cap CPU, memory, and the rate of tool calls. This contains a runaway or hijacked server grinding through your API and keeps one tool from starving the rest.
The practical test mirrors the one for any tool: if an attacker fully controlled this server, what is the worst it could do from inside its sandbox? If the honest answer is “nothing reaches the host or the network,” your isolation is doing its job. If it is “it has my cloud keys and open internet,” you have a flat dependency wearing the costume of a tool.
How do these controls fit together?
No single control fixes MCP security, because the CVE classes attack different layers. Isolation is the foundation, but it works because the others narrow what is even reachable.
- Treat the server as untrusted. This is the mindset that makes the rest non-optional. Reputation and official labels do not grant trust; isolation does.
- Review and pin tool definitions. Catch tool poisoning at the metadata layer, and turn rug-pulls into visible diffs instead of silent swaps.
- Sandbox per server. Contain command injection and path traversal inside a process and filesystem the bug cannot escape.
- Control egress and scope credentials. Neutralize SSRF and exfiltration by leaving the attacker nowhere to send data and nothing privileged to steal.
Each layer fails differently — a sandbox can be misconfigured, an egress rule can have a gap, a credential can be scoped too wide — so the point of stacking them is that an attacker has to defeat all four to do real damage. Compromise the server and escape its sandbox and find an open egress path and hold a credential worth stealing. Any one control on its own eventually fails; together they bound the worst case.
Start with the servers that touch untrusted input or hold real credentials, because that is where the irreversibility lives. Inventory every MCP server your agents connect, pin and review its tool definitions, give it a sandbox with a read-only filesystem, an egress allowlist, and a scoped credential — and then widen its reach only when the job provably needs it. An MCP server you have isolated is a tool. An MCP server you have merely installed is a dependency with a foothold in your agent.
FAQ
What is an MCP server, and why is it a security boundary?
An MCP (Model Context Protocol) server is a process that exposes tools, resources, and prompts to an AI agent over a standard protocol. It is a security boundary because the agent will call its tools and act on its outputs with real privileges — file access, network access, credentials. The server is effectively a third-party dependency that executes inside your agent’s trust zone, so a flaw in it becomes a flaw in your agent.
What kinds of CVEs have been found in MCP servers?
The recurring classes are command injection (the server passes agent-supplied arguments into a shell), path traversal (a filesystem server escapes its intended root), SSRF and unvalidated URL fetching (a server fetches attacker-controlled URLs from inside your network), and tool poisoning or rug-pull (a server’s tool description or behavior changes to inject hidden instructions). Most are ordinary application-security bugs, made dangerous because an LLM, not a careful human, supplies the inputs.
How is tool poisoning different from prompt injection?
Prompt injection lives in the data an agent reads. Tool poisoning lives in the tool definition itself — the name, description, or parameter schema that the MCP server advertises. Because the agent treats tool metadata as trusted instructions, a malicious or compromised server can embed directives there that the user never sees, and a benign-looking server can later “rug-pull” by changing that metadata after it has earned trust.
Should I run each MCP server in its own sandbox?
Yes, where the server is third-party or handles untrusted input. Treat each server as an untrusted dependency: run it in its own container or microVM with a read-only filesystem, no ambient credentials, an egress allowlist, and only the host paths it genuinely needs. Isolation per server means one compromised tool cannot reach another server’s secrets or the host.
How do I stop a malicious MCP server from exfiltrating data?
Cut its network reach. A server that only needs to read local files should have no outbound network at all; one that calls a specific API should be restricted to that destination by an egress allowlist, not given open internet access. Combine that with scoped, short-lived credentials so even a server that does talk to the network cannot reach data outside its job, and log every call so exfiltration attempts are visible.
Are official or popular MCP servers safe to trust by default?
No. Popularity and an official label reduce but do not remove risk: published CVEs have hit widely used servers, and an installed server can be updated or its upstream compromised after you vet it. Pin versions, review the actual tool definitions, isolate the server regardless of its reputation, and re-verify on update. Trust is a property of your isolation, not of the server’s badge.
What is the single most important control for MCP security?
Isolation with least privilege per server. If every MCP server runs sandboxed, with only the filesystem paths, network destinations, and credentials its job requires, then the entire class of MCP CVEs — command injection, path traversal, SSRF, tool poisoning — is bounded: the attacker may compromise one tool, but the blast radius stops at that sandbox instead of reaching your host, your secrets, or your other tools.
Frequently asked
What is an MCP server, and why is it a security boundary?
An MCP (Model Context Protocol) server is a process that exposes tools, resources, and prompts to an AI agent over a standard protocol. It is a security boundary because the agent will call its tools and act on its outputs with real privileges — file access, network access, credentials. The server is effectively a third-party dependency that executes inside your agent's trust zone, so a flaw in it becomes a flaw in your agent.
What kinds of CVEs have been found in MCP servers?
The recurring classes are command injection (server passes agent-supplied arguments into a shell), path traversal (a filesystem server escapes its intended root), SSRF and unvalidated URL fetching (a server fetches attacker-controlled URLs from inside your network), and tool poisoning or rug-pull (a server's tool description or behavior changes to inject hidden instructions). Most are ordinary application-security bugs, made dangerous because an LLM, not a careful human, supplies the inputs.
How is tool poisoning different from prompt injection?
Prompt injection lives in the data an agent reads. Tool poisoning lives in the tool definition itself — the name, description, or parameter schema that the MCP server advertises. Because the agent treats tool metadata as trusted instructions, a malicious or compromised server can embed directives there that the user never sees, and a benign-looking server can later 'rug-pull' by changing that metadata after it has earned trust.
Should I run each MCP server in its own sandbox?
Yes, where the server is third-party or handles untrusted input. Treat each server as an untrusted dependency: run it in its own container or microVM with a read-only filesystem, no ambient credentials, an egress allowlist, and only the host paths it genuinely needs. Isolation per server means one compromised tool cannot reach another server's secrets or the host.
How do I stop a malicious MCP server from exfiltrating data?
Cut its network reach. A server that only needs to read local files should have no outbound network at all; one that calls a specific API should be restricted to that destination by an egress allowlist, not given open internet access. Combine that with scoped, short-lived credentials so even a server that does talk to the network cannot reach data outside its job, and log every call so exfiltration attempts are visible.
Are official or popular MCP servers safe to trust by default?
No. Popularity and an official label reduce but do not remove risk: published CVEs have hit widely used servers, and an installed server can be updated or its upstream compromised after you vet it. Pin versions, review the actual tool definitions, isolate the server regardless of its reputation, and re-verify on update. Trust is a property of your isolation, not of the server's badge.
What is the single most important control for MCP security?
Isolation with least privilege per server. If every MCP server runs sandboxed, with only the filesystem paths, network destinations, and credentials its job requires, then the entire class of MCP CVEs — command injection, path traversal, SSRF, tool poisoning — is bounded: the attacker may compromise one tool, but the blast radius stops at that sandbox instead of reaching your host, your secrets, or your other tools.