Threats and Vulnerabilities

When MCP Trust Boundaries Break: 3 Silent but Critical Risks

MCP servers are designed to enforce structure. They define typed tools, document expected inputs, and separate public access from admin privileges. That structure can create an impression of safety: if the tools are well-defined and the roles are clear, the integration must be under control.

When MCP Trust Boundaries Break: 3 Silent but Critical Risks
Ilya Olchikov
April 6, 2026
8 minutes

Table of Contents

  1. Introduction
  2. Server-Side File Read via get_metadata.
  3. User Enumeration via search_users
  4. Prototype Pollution via update_user
  5. What These Three Paths Have in Common
  6. How to Prevent MCP Trust Boundary Failures
  7. Conclusion

Introduction

MCP servers are designed to enforce structure. They define typed tools, document expected inputs, and separate public access from admin privileges. That structure can create an impression of safety: if the tools are well-defined and the roles are clear, the integration must be under control.

That impression is wrong. Structure does not equal safety. An MCP tool can be perfectly typed, clearly documented, and still violate fundamental trust boundaries. When the tool proxies backend behavior that mishandles external input, exposes too much data, or blindly trusts attacker-controlled payloads, the MCP layer inherits every one of those failures and makes them easier to reach.

Broken Crystals demonstrates this with three tools that look routine but silently break critical trust boundaries: get_metadata, search_users, and update_user. None of them executes code or spawns processes. None of them requires admin access. All three are public MCP capabilities that any connected agent or client can discover and call after a single initialization handshake.

That is what makes trust boundary failures in MCP dangerous. They do not announce themselves. There is no error, no crash, no obvious sign that something went wrong. The tool returns a clean response, and the boundary has already been crossed.

1. Server-Side File Read via get_metadata

The get_metadata tool is exposed as a public MCP capability. Its contract is simple: accept an XML string and return parsed output. Under the hood, it proxies the user-supplied XML directly into the backend XML parser with external entity processing enabled.

That configuration is the problem. The backend XML parser resolves external entities, which means the caller can define an entity that points to a local file and have its contents included in the parsed output. In practice, a single call to get_metadata can retrieve sensitive server-side files like /etc/passwd or application configuration files.

This is a textbook XML External Entity attack, but MCP changes the threat model. The attacker does not need to find an obscure XML upload form or intercept a SOAP request. The tool is listed in the MCP capability set, the input schema says it accepts an XML string, and the response comes back structured and ready to parse. An AI agent or automated workflow can discover and exploit this without any prior knowledge of the backend.

The trust boundary that breaks here is between external input and internal resources. The MCP tool accepts untrusted XML from any connected client and passes it to a parser configured to resolve references to the local filesystem. The tool treats the XML as data. The parser treats it as instructions.

The fix is to disable external entity resolution entirely. If an MCP tool must accept XML, it should never allow the input to reference external resources, local files, or internal network endpoints.

2. User Enumeration via search_users

If get_metadata breaks the boundary between input and internal resources, search_users breaks the boundary between public and private data.

In Broken Crystals, search_users is a public MCP tool that accepts a name prefix and returns matching users. Moreover, the tool has no authentication requirement – any MCP session, including an unauthenticated guest session, can call it.

The deeper problem is not just that the tool is open. It is what it returns. Instead of a minimal result like a display name, the response includes email addresses, phone numbers, internal identifiers, and other fields that should never be exposed to unauthenticated callers. A single call with a short prefix like “name”: “a” can return dozens of complete user records.

This is broken access control in its most common form: the data exists, the tool returns it, and nothing in between enforces who should see it. But MCP amplifies the risk. An AI agent with MCP access can call search_users programmatically, iterate through name prefixes, and enumerate the entire user directory in seconds. The tool is discoverable through tools/list, the input is a single string, and the output is structured JSON ready for downstream processing.

That matters because user enumeration is rarely the end goal. It is the first step in credential stuffing, phishing, privilege escalation, and social engineering. Once an attacker has a full user directory – names, emails, phone numbers, internal IDs – every other attack becomes easier to target.

The fix requires two changes. First, the tool must enforce authentication. Public MCP tools should not return user data to unauthenticated sessions. Second, the output must be minimized. Even authenticated callers should receive only the fields necessary for the specific use case, not the full internal user record.

3.  Prototype Pollution via update_user

The most subtle trust boundary failure in the MCP layer is update_user.

Broken Crystals exposes a public MCP tool that accepts a JSON payload with user fields like name, email, username, and phone. The tool picks those allowed fields from the input and includes them in the response. That sounds safe. But the implementation also processes the __proto__ key in the payload and merges whatever it contains into the returned object.

This means an attacker can call update_user with a payload that includes “__proto__”: {“role”: “admin”}, and the response will include the new role alongside the legitimate fields. The tool does not validate, filter, or reject the __proto__ key. It treats attacker-controlled prototype fields as first-class output.

This is prototype pollution exposed through an agent-facing interface. In traditional web applications, prototype pollution typically requires finding an unsafe merge or copy operation buried deep in the code. In MCP, the tool explicitly accepts and returns polluted properties. The attack does not require any guesswork. The caller simply includes __proto__ in the payload, and the tool cooperates.

The risk extends beyond the immediate response. If any downstream consumer of this tool’s output uses the returned object for authorization checks, configuration, or further processing, the injected properties can alter application logic. A role: “admin” field that appears in the response because of prototype pollution can become a real privilege escalation if the consuming code does not distinguish between legitimate and injected properties.The fix is straightforward: never process __proto__ from user-controlled input. MCP tools should explicitly allowlist the fields they accept and return, and strip any key that can manipulate the object prototype chain before processing.

What These Three Paths Have in Common

These issues are different technically, but they share the same architectural problem: MCP tools that silently cross trust boundaries because the backend behavior they proxy was never designed to be agent-facing.

get_metadata breaks the boundary between external input and internal resources. search_users breaks the boundary between public access and private data. update_user breaks the boundary between trusted structure and attacker-controlled object properties. In each case, the underlying vulnerability is well-known. What changes with MCP is that these vulnerabilities are wrapped in a discoverable, typed, and callable interface that any connected client can reach.

None of these tools requires admin access. None of them produces errors or warnings when exploited. The responses come back clean and structured, which makes the boundary violations invisible to casual inspection and easy to chain into larger workflows.

That is why trust boundary analysis matters at the MCP layer. If a tool can read local files, expose user records, or accept prototype-polluted payloads, those are not backend problems that MCP inherits passively. They are MCP-layer risks that need to be reviewed, tested, and mitigated directly.

How to Prevent MCP Trust Boundary Failures

Start by treating every MCP tool as its own trust boundary, not as a transparent proxy to something behind it. Treat every tool input as untrusted, every tool output as a data exposure decision, and every public tool as a potential entry point for enumeration and chaining.

More specifically: review what each tool proxies and whether the backend behavior was designed for the access level the MCP tool grants. A backend endpoint that was built for authenticated internal use does not become safe because an MCP tool definition calls it “public.” A parser configuration that was acceptable for server-to-server communication is not acceptable when the input comes from an unauthenticated agent session.

Most importantly, test the MCP tools for trust boundary violations directly. Broken Crystals is valuable because it demonstrates these failures end-to-end: unauthenticated sessions calling public tools, structured inputs crossing into internal resources, and clean responses that reveal exactly how much was exposed. That is the level where real agent security problems appear – not in the tool definition, but in what the tool actually does when called.

Conclusion

Trust boundary failures through MCP do not require sophisticated exploits or novel attack techniques. They happen when existing backend behavior is exposed through an interface designed for discovery, automation, and structured interaction. That makes familiar weaknesses silent, scalable, and easy to chain.

For teams adopting MCP, the takeaway is clear: do not assume that tool definitions enforce safety. Review what each tool proxies, restrict what it returns, and validate what it accepts. If security validation only covers the backend API layer, the most important trust boundary failures may still be sitting in the MCP tools above it, waiting for the first agent to call tools/list.

What Our Customers Say About Us

"Empowering our developers with Bright Security's DAST has been pivotal at SentinelOne. It's not just about protecting systems; it's about instilling a culture where security is an integral part of development, driving innovation and efficiency."

Kunal Bhattacharya | Head of Application Security

"Bright DAST has transformed how we approach AST at SXI, Inc. Its seamless CI/CD
integration, advanced scanning, and actionable insights empower us to catch
vulnerabilities early, saving time and costs. It's a game-changer for organizations aiming to
enhance their security posture and reduce remediation costs."

Carlo M. Camerino | Chief Technology Officer

"Bright Security has helped us shift left by automating AppSec scans and regression testing early in development while also fostering better collaboration between R&D teams and raising overall security posture and awareness. Their support has been consistently fast and helpful."

Amit Blum | Security team lead

"Bright Security enabled us to significantly improve our application security coverage and remediate vulnerabilities much faster. Bright Security has reduced the amount of wall clock hours AND man hours we used to spend doing preliminary scans on applications by about 70%."

Alex Brown

"Duis aute irure dolor in reprehenderit in voluptate velit esse."

Bobby Kuzma | ProCircular

"Since implementing Bright's DAST scanner, we have markedly improved the efficiency of our runtime scanning. Despite increasing the cadence of application testing, we've noticed no impact to application stability using the tool. Additionally, the level of customer support has been second to none. They have been committed to ensuring our experience with the product has been valuable and have diligently worked with us to resolve any issues and questions."

AppSec Leader | Prominent Midwestern Bank

Book a Demo

See how Bright validates real risk inside your CI/CD pipeline and eliminates false positives before they reach developers.

Our clients:
SulAmerica Barracuda SentinelOne MetLife Nielsen Heritage Bank Versant Health