MCP security isn’t inevitable: closing the gaps before the ecosystem hardens
Turning best practices into enforcement surfaces before correlated failures become normal
MCP is quickly becoming default infra for tool-calling AI systems. That's good for interoperability but can be bad for risk if we don't start acting on lessons learned from other technology domains.
Two recent MCP reports make that risk concrete. Cyata showed an exploit chain that weaponizes Anthropic’s official Git + filesystem MCP servers to reach remote code execution via indirect prompt injection (malicious content steers tool use). Here the attacker doesn’t hack the server in the classical sense. Instead, they control content the agent reads (a repo file, a README, an issue), and that content steers tool use. Each tool looks reasonable on its own. In combination, and under realistic permissions, the chain can produce outcomes that look like developer-tool compromise and can escalate from there. At the same time, BlueRock.io disclosed a server-side request forgery (SSRF) issue in Microsoft’s MarkItDown MCP server that can make the server fetch internal network resources; in cloud deployments that can translate into cloud-metadata credential leakage and broader account compromise. BlueRock also analyzed 7,000+ MCP servers and suggests ~36.7% may share similar SSRF exposure patterns. Even if the exact fraction is disputable and exploitability varies by deployment, the directional signal is the same: the ecosystem is replicating fetcher patterns faster than it is converging on safe defaults.
These are not the only MCP-shaped findings in recent months. We’ve seen critical issues in MCP-adjacent developer tooling, and we’ve seen ecosystem-layer incidents where a compromise in a hosting or distribution layer exposed secrets at scale and impacted many servers at once. We’ve also seen repeated warnings that a non-trivial number of MCP servers wind up deployed with weak or missing authentication. Taken together, the key insight isn’t that MCP has vulnerabilities, but instead that MCP is accumulating repeatable vulnerability classes across an ecosystem that is scaling faster than its enforceable security defaults.
That is systemic risk: risk that spans many organizations because it is produced by shared substrates and shared habits. A protocol becomes popular; popular implementations and templates become the default; defaults get copied into the long tail; the attacker’s job shifts from bespoke exploitation to class reuse.
The question isn’t whether MCP is secure. Rather, it is what security equilibrium MCP should converge on as it matures. Standards become risk reducers when they standardize not only the interface, but the security posture and enforcement surfaces. Standards become risk concentrators when interoperability scales faster than secure-by-default deployment, leaving serious operators to fence off the ecosystem while the long tail remains brittle.
I’ll say more on this below, but it’s worth underlining here too: the MCP ecosystem is not ignoring security. A lot of positive work is already happening. My argument here is that security convergence is not inevitable, even when good work is underway. Closing the remaining gaps requires deliberate choices that change what the ecosystem defaults to.
Why the recent reports matter
MCP started as a tool-calling interoperability layer. That framing invites a narrow threat model: one server, one tool, one integration. But MCP’s value is that it makes tool discovery and tool invocation cheap, standardized, and composable. As adoption grows, MCP becomes connective tissue for agents touching repositories and CI, local files and apps, internal tickets and docs, and networked services. Once you’re connective tissue, you are also a substrate that other people build on, package, and deploy in ways you don’t control.
This is the environment in which this week’s MCP security reports arrive. The Git/filesystem story is fundamentally about composition risk: chains of individually reasonable capabilities become a capability escalator when the model is steered by untrusted content. The MarkItDown story is fundamentally about fetcher risk: once fetch-and-convert-URL becomes a common server pattern, SSRF becomes a common class, and cloud deployment realities turn SSRF into a high-leverage pivot. Different mechanics, same systemic dynamic: MCP makes it easy to connect powerful primitives, and ecosystems replicate whatever is easiest.
Two implications follow: 1) the center of gravity is not bugs in code but instead variance in security posture across thousands of servers and deployment patterns; 2) some of the most effective defense moves are ones that reduce that variance: enforceable baselines, conformance tests, governed distribution, and defaults that make the safe path the easiest path.
Protocols can reduce risk, but they can also concentrate it
It’s worth being precise about what standards do. They concentrate attention, which is good. Popular substrates attract scrutiny, better tooling, better scanning, and clearer operational norms. A dominant protocol can be easier to secure than a thousand bespoke interfaces, because defenders can invest in shared controls.
But standards also concentrate blast radius, especially early in their lifecycle when the ecosystem is converging on convenient defaults. If the quickest path to making a system work is permissive URL fetching, broad filesystem scope, or ambiguous authentication posture, then this risks becoming the center of gravity. Thousands of servers copy the same patterns. Correlated failure modes appear across many organizations (not to mention vulnerabilities at the individual system level across all systems repeating that risky pattern).
The systemic-risk lens for MCP is not that vulnerabilities exist. It is that patterns are repeated across many independent parties at an ecosystem level. The question we face now is whether the ecosystem will create enforcement surfaces that reliably narrow variance and bound impact, or alternatively normalize convenience defaults that continue to live in the long tail?
MCP is already growing a security spine
It’s important to acknowledge security work already underway for MCP.
At the protocol layer, the authorization is being worked on, bringing it somewhat in alignment with modern OAuth-derived patterns rather than bespoke token designs. MCP security best-practices guidance treats the real world as messy. It calls out that MCP servers often run with user privileges, that toolchains get composed, and that implementers should think in terms of least privilege, sandboxing, and explicit consent surfaces. This is the protocol community internalizing the difference between simple abstractions and more realistic security boundaries.
At the platform layer, the mechanisms that turn a standard into a risk reducer are emerging: registries, allowlists, policy gates. Microsoft’s direction on a Windows MCP server registry is the clearest articulation: baseline requirements such as code signing for provenance and revocation, package identity, declared privileges, constraints against silent tool-definition mutation, and security testing for inclusion. These are enforcement primitives. They change incentives and make unsafe defaults harder to ship.
At the community layer, guidance is becoming operator-facing rather than purely implementer-facing. OWASP has published practical advice for securely using third-party MCP servers, focusing on governance workflows, sandboxing, secure discovery, and the reality that third-party tool ecosystems behave like supply chains. There is also visible momentum toward conformance tooling, which offer some teeth for the maturing ecosystem.
Finally, the findings-to-fixes loop is working in some key cases. High-severity issues have led to hardening changes and faster patch propagation than would have been typical for a young ecosystem.
All of this is progress. The point is not that the MCP community is not acting on security. Rather it is that progress of this sort can coexist with unstable equilibrium. The remaining gaps are structural and will not close themselves without deliberate ecosystem choices.
The gaps that remain
Four gaps show up repeatedly across the recent findings and across how MCP servers are built and deployed.
Adoption still outruns secure-by-default deployment. MCP spans local developer experimentation, internal enterprise deployments, and internet-reachable services. Ecosystems tend to normalize whatever is easiest in the local dev path, and that posture leaks outward. Even when documentation warns against insecure configurations, the existence of low-friction insecure modes becomes a steady source of real-world exposure. This is not primarily a documentation problem. It is a defaults and gating problem, and it has to be solved with enforcement surfaces rather than admonitions.
Composition risk is not systematically gated. The Git plus filesystem chain is an archetype: each server is defensible in isolation, but the graph becomes dangerous when the model is steered. Composition risk persists because it emerges at the system level. Tool authors reason locally; integrators reason locally; attackers reason globally. Without a capability-scoping contract that hosts can enforce and without routine composition testing, the same pattern will recur with different servers.
SSRF remains a correlated class across fetcher archetypes. A protocol that makes it easy to plug in URL-fetch-convert servers will create a large population of fetchers. Fetchers without strict egress defaults, redirect controls, and explicit allowlists become systemic risk patterns, especially in cloud environments where internal control planes and metadata endpoints are high-value targets. The exact prevalence of vulnerable fetchers can be argued about. The class-level issue does not depend on perfect prevalence estimates. If fetchers proliferate faster than guardrails, systemic risk accumulates.
The supply-chain layer remains a soft underbelly. Ecosystem-layer incidents are reminders that systemic risk does not require protocol flaws. A single compromise in a hosting provider, marketplace, build pipeline, or registry can expose secrets at scale or push malicious updates across a wide surface area. Without integrity, provenance, version pinning norms, and revocation mechanisms that work across fleets, the long tail remains brittle by construction.
These gaps point to missing enforcement primitives: deployer-usable baselines, conformance suites that encode recurring classes of failure, governed distribution, isolation patterns, and mechanisms that make the safe path easy.
What MCP can learn from other domains
A good way to reason about MCP’s potential trajectories is to learn from domains that have lived through a similar dynamic in the past: standard becomes substrate; adoption scales; ecosystem either narrows variance and makes security enforceable or it hardens around convenience defaults and leaves orgs defending themselves by doing perimeter fencing, etc.
Let’s consider three examples:
OAuth and the security posture layer
OAuth is a web standard for delegated authorization. It enables a client to access a resource server under an authorization policy without the user handing the client long-lived credentials. In practice it underpins a vast portion of modern API authorization and sign-in-with flows (often via OIDC layered on top for identity).
OAuth is a helpful example because its security story is not that the initial spec already solved for security. Quit the opposite. Early OAuth deployments included patterns that turned out to be risky or easy to implement incorrectly, such as flows that exposed tokens in places they didn’t belong, loose redirect URI validation, and brittle assumptions about which clients could safely hold secrets. Over time, the ecosystem built a security posture layer on top of the base standard: threat models that reflected real deployments; best-current-practice guidance that deprecated unsafe patterns; specific mitigations that closed common classes of exploitation; and, crucially, profiles and conformance regimes that narrowed variance.
The lesson for MCP is not that it should use OAuth or OAuth patterns. MCP is already aligning authorization with OAuth-derived patterns. The key lesson is that a standard becomes a risk reducer when the ecosystem makes security posture testable and enforceable. Claims made that a technology supports OAuth became meaningful once deployers could distinguish support that was demonstrably safe from support that looked good on paper or in a demo but had little or no hard demonstration. MCP needs the same kind of variance reduction, especially around high-risk capability classes and deployment modes.
Supply-chain security and the distribution boundary
Supply-chain security is not a single technology. It is the recognition that modern software is assembled from dependencies distributed through registries, build pipelines, and marketplaces. As soon as it becomes cheap to install a component, compromise paths shift toward distribution: malicious packages, compromised maintainers, poisoned build pipelines, and hostile updates.
The industry response has converged on a set of enforcement primitives: artifact identity; integrity checks such as signing; provenance signals from build systems; dependency inventory and SBOM practices; and mechanisms for rapid revocation and advisories. None of these is perfect, and supply-chain security remains a contested and evolving area. The important point is that mature ecosystems created ways to enforce basic integrity properties at scale rather than relying on manual trust.
This maps directly onto MCP. The moment MCP servers are discoverable and installable through registries and marketplaces, the ecosystem becomes a dependency graph. Dependency graphs do not become safer because everyone reads best practices. They become safer when distribution has integrity properties and when policy gates are built into the deployment path: publisher identity; signed artifacts and metadata; declared privileges; version pinning norms; and revocation that is fast and visible across fleets. Platform moves toward registries and allowlists are encouraging because they embed governance into the workflow. The remaining work is to make those primitives common and interoperable rather than siloed.
UPnP and the convenience-default equilibrium
UPnP is a family of protocols designed for device discovery and control in local networks, widely used to reduce friction for consumer devices. It succeeded because it made things work automatically without requiring users to understand networking.
UPnP is a useful warning case because it scaled rapidly on an implicit trust assumption: that the local network is a safe environment and that convenience-first discovery and control would remain within that boundary. Reality violated that assumption through exposure beyond intended scope, heterogeneous implementations, and uneven patching across device fleets with long lifecycles. The ecosystem struggled to converge on enforceable security posture across the long tail. The operational outcome for many security-conscious operators was often to disable it or to fence it. Meanwhile, most did not, leaving the convenience-first long tail to persist, grow, fester.
The lesson here for MCP is not that discovery protocols are inherently bad, but that guidance does not beat or create defaults, and early behavioral defaults can harden into an equilibrium that becomes hard to change. MCP can end up in an UPnP-like world if security remains optional enterprise hardening and if secure-by-default templates are not the easiest path for developers. In that equilibrium, serious operators increasingly restrict third-party MCP servers, the ecosystem fractures into governed islands surrounded by a risky long tail, and systemic risk remains high even as the protocol improves.
OAuth and supply-chain security show how standards become risk reducers: profiles, conformance, integrity, and revocation. UPnP shows what happens when a substrate scales faster than its enforceable security posture.
What teams deploying MCP can do today
Inventory and ownership: Maintain an MCP bill of materials that includes server identity, version, deployment mode, owner, and external systems touched. Treat MCP servers as dependencies with lifecycle management.
Identity and privilege separation: Use per-server identities and least privilege in external systems; avoid shared credentials across servers; assume compromise of one tool is plausible and design so it does not become compromise of other things.
Scope and isolation by default: Constrain filesystem access with explicit path allowlists; default to read-only unless writing is required; isolate servers with sandboxing and process boundaries appropriate to the environment; treat running with user privileges as a high-risk default that needs compensating controls.
Egress controls for fetchers: For any server that fetches URLs or retrieves remote content, enforce an explicit egress policy; default-deny internal/private/link-local ranges unless explicitly allowed; use strict redirect policies and explicit allowlists; treat cloud metadata endpoints and internal control planes as protected resources by default.
Composition testing: Build a small, repeatable suite that probes indirect prompt injection steering, unsafe tool sequences, and SSRF vectors against the actual tool set. Convert findings into regression tests and policy gates.
Distribution hygiene: Prefer registry or allowlist patterns where available; pin versions; require basic provenance hygiene for third-party servers; define what approved means in the host layer and enforce it.
Telemetry aligned to the threat model: Log tool invocation sequences and policy denials; monitor for abnormal tool graphs, unexpected internal fetch attempts, and unscoped file writes. Treat anomalies as signals of steering and composition risk.
What the MCP ecosystem needs to do today
Publish a deployer-usable baseline: Define a control-objective baseline for production eligibility that is compatible with MCP authorization and best-practices direction. Focus on properties that can be enforced across implementations rather than prescribing mechanisms.
Back the baseline with conformance suites: Convert recurring failure classes into test vectors and suites. Prioritize SSRF patterns, scope escapes, token handling and session behavior, resource-limiting and safe parsing, and tool-definition stability.
Make secure templates the default: Treat reference implementations and quickstarts as policy objects. Ship scoped capabilities, safe egress posture for fetchers, and explicit identity boundaries.
Standardize registry governance primitives: Establish expectations for publisher identity, integrity, declared privileges, version pinning norms, and rapid revocation/advisories. Make these properties easy for hosts and enterprises to evaluate.
Improve the pipeline from findings to defenses: When disclosures arrive, extract the class; add test vectors; update reference templates; publish clear upgrade guidance; and measure adoption in the long tail rather than assuming awareness equals remediation.
Support composition-aware controls in hosts: Provide host environments with the primitives to reason about capability graphs, not just individual tool calls, and to require explicit approvals for high-risk transitions.
There is nothing preordained about MCP’s security future. The ecosystem has momentum: authorization work, best practices, registry and allowlist directions, conformance tooling, and faster response to findings. It also has real systemic-risk pressure: recurring classes like SSRF in fetchers; composition-driven exploit chains; insecure deployment paths that persist in the long tail; and supply-chain vulnerabilities that can produce fleet-scale blast radius.
The difference between MCP as a risk reducer and MCP as a risk concentrator is whether security posture becomes default, testable, and enforceable before today’s templates harden into tomorrow’s substrate. That is not a matter of intent. It is a matter of baselines, tests, registries, defaults.
The practical gap underneath all of this is that best practices and guidelines are not themselves an enforcement surface. Teams need a lightweight way to turn MCP security posture into something that can be checked, gated, and communicated across builders, deployers, and registries. To make that concrete, I’m proposing an MCP Production Baseline v0 in the appendix: a deployer-facing set of control objectives and evidence artifacts that helps reduce systemic risk by narrowing variance across deployment classes, and by makes production-ready security claims more testable and verifiable.
Appendix: MCP Production Baseline v0
This appendix proposes a deployer-facing baseline intended to reduce risk by narrowing variance in security posture across MCP servers and deployments. It is written at the level of control objectives and evidence artifacts. It does not prescribe specific authentication mechanisms or protocol-level choices beyond the direction already present in MCP authorization and best-practices work. The intent is to provide a practical checklist that teams can use today, and that registries and host platforms can use as a gating surface, without turning this document into a standards-track specification.
Deployment classes
This baseline distinguishes four common deployment classes because required controls differ by deployment mode.
Local stdio:
What it is: the host starts a server process and communicates over stdio (no listening port);
When it’s used: local IDE/desktop agent workflows and early prototyping;
Who uses it: individual developers on a single machine;
Threat-model shift: low network exposure, but high impact if untrusted content steers powerful local tools running under developer privileges.
Local loopback HTTP:
What it is: the server listens on localhost and is reachable by other local processes;
When it’s used: local multi-process stacks (agent framework + tools), sometimes with browser-adjacent UX;
Who uses it: developers and teams building local agent runtimes;
Threat-model shift: adds a broader local attack surface (cross-process calls, local web-origin gotchas) compared to stdio, while still inheriting local privilege impact.
Remote internal:
What it is: the server is reachable over a private network or internal service mesh;
When it’s used: shared internal tools (tickets/docs/repos/data) and team-scale agent deployments;
Who uses it: platform and product teams inside an organization;
Threat-model shift: becomes a shared service boundary where authN/authZ, caller identity, and blast-radius containment matter, and where fetcher/SSRF paths can pivot into internal control planes.
Remote internet-exposed:
What it is: the server is reachable over public networks;
When it’s used: SaaS-style deployments and integrations meant to be called from outside a single trust domain;
Who uses it: vendors and teams exposing MCP-backed capabilities to external users or customers;
Threat-model shift: assumes hostile traffic at scale, so hardening against remote abuse (auth, rate limits, input handling, observability) becomes a first-order requirement rather than a compensating control.
The baseline focuses primarily on remote internal and remote internet-exposed deployments. Local stdio and loopback deployments are included where the control objective is still relevant and common failure modes exist.
How to read the baseline
Each control objective is expressed as an invariant with expected evidence. Mechanisms may vary by deployment and platform. The goal is that the property holds and can be demonstrated.
Host baseline
Capability bounding is enforced
Invariant: Tools execute only within explicit capability bounds for filesystem, network, and external systems.
Evidence: A machine-readable capability policy; deny logs demonstrating enforcement; tests attempting scope violations.
Applies to: All classes, with stricter expectations for remote internal and internet-exposed.
High-risk actions are policy-gated
Invariant: High-risk operations such as write, exec, or network access beyond allowlists are denied by policy or require explicit approval through the host.
Evidence: Policy rules; approval/audit logs where approvals exist; regression tests verifying denials without approval.
Applies to: Remote internal; remote internet-exposed.
Composition risk is tested against the deployed tool set
Invariant: The deployment includes a minimal, repeatable suite that probes tool-chaining and indirect prompt injection steering against the actual server set and host configuration.
Evidence: Test pack; CI results; documented known unsafe combinations and corresponding policy blocks or approvals.
Applies to: All classes where untrusted content can enter the agent context; mandatory for remote internal and internet-exposed.
Secrets and identities are isolated
Invariant: Compromise of one server does not grant lateral access to other servers or upstream systems by default. No ambient/shared credentials across servers unless explicitly justified.
Evidence: Identity map showing server-to-principal mappings and permissions; secrets storage policy; periodic review artifact.
Applies to: Remote internal; remote internet-exposed.
Telemetry supports incident response without creating new exfiltration paths
Invariant: Tool invocation and policy decisions are auditable, and sensitive data is controlled in logs.
Evidence: Structured event schema; redaction rules; access controls and retention policy; sample incident runbook.
Applies to: Remote internal; remote internet-exposed.
Server baseline
Access control is enforced in shared and remote deployments
Invariant: Servers are not reachable by unauthorized callers in remote internal and internet-exposed modes.
Evidence: Deployment declaration; access control configuration; negative access tests; audit logs showing caller identity where available.
Applies to: Remote internal; remote internet-exposed.
Privileges are declared and stable enough for governance
Invariant: Servers publish a privilege or capability manifest describing what they can touch and the scopes they require; changes in privileges are versioned and visible.
Evidence: Privilege manifest; change log; policy evaluation output; version pinning guidance.
Applies to: All classes where servers are shared or reused beyond a single developer.
Fetcher behavior is governed when network retrieval is supported
Invariant: Any server that fetches URLs or retrieves remote content operates under an explicit egress policy. Internal and link-local destinations are blocked unless explicitly allowed. Redirect behavior is constrained by policy.
Evidence: Egress policy; deny logs; regression tests covering common SSRF vectors and redirect behavior; documented exception process for internal access.
Applies to: All classes where fetch is enabled; mandatory for remote internal and internet-exposed.
Resource limits and safe input handling are in place
Invariant: Servers enforce basic abuse resistance for untrusted inputs: timeouts, size limits, concurrency limits where appropriate, and safe parsing practices appropriate to their function.
Evidence: Config defaults; tests for oversized inputs and timeouts; monitoring signals for throttling and failures.
Applies to: All classes; mandatory for internet-exposed.
Security-relevant tool changes cannot be silent
Invariant: Tool identity and security-relevant properties do not change without visibility to the host and governance layer. Dynamic tools are permitted, but changes that affect privileges or semantics are versioned and require policy re-evaluation.
Evidence: Versioning policy; signed or integrity-protected manifests where applicable; host-visible change notifications; approval workflow artifact.
Applies to: Remote internal; remote internet-exposed; recommended elsewhere.
Registry and distribution baseline
Publisher identity and artifact integrity are available for governed distribution
Invariant: Servers distributed through registries or marketplaces are attributable to a publisher identity and protected against silent tampering.
Evidence: Identity metadata; integrity verification steps; documentation for consumers on verification.
Applies to: Any registry-distributed server intended for production use.
Declared privileges are mandatory metadata
Invariant: Registry entries include declared privileges and scopes sufficient for host policy evaluation before enablement.
Evidence: Registry schema; sample entries; policy evaluation output.
Applies to: Registry-distributed production servers.
Fleet-scale advisory and revocation mechanisms exist
Invariant: A newly discovered high-risk issue can be communicated and acted on quickly across fleets using that registry.
Evidence: Advisory channel; revocation or quarantine mechanism; operational playbook for disabling or forcing upgrades.
Applies to: Registry-distributed production servers.
Notes on scope
This baseline is intentionally conservative in its language. It defines properties that are broadly accepted in secure ecosystems and directly target the vulnerability classes that are already showing up in MCP deployments: composition risk, fetcher risk, insecure exposure, and supply-chain blast radius. It avoids prescribing specific authentication mechanisms or transport-level choices because those vary across environments and are already an area of active MCP design work. The goal is to narrow variance where it matters and to provide deployers, registries, and host platforms with gating surfaces that can be operationalized.
The baseline should evolve as the ecosystem learns. When a new vulnerability class becomes salient, it should be translated into a new test vector and where appropriate into a new control objective or tighter evidence requirements. The findings-to-conformance loop is the mechanism that turns an ecosystem’s growing security spine into systemic-risk reduction.



The systemic risk framing is spot on. The comparison to UPnP really drove it home for me - I rember dealing with the fallout from UPnP vulnerabilities in IoT devices and it was exacty this pattern of convenience-first defaults that nobody could roll back. The MCP baseline stuff in the appendix is practical tho, way better than just more guidance docs that people ignore. Governance primitives baked into distribution is the only thing that actually scales.