Secure Configuration Baselines for MCP Server Deployments
Protocol leaves three security gaps; a new benchmark fills them.

The Model Context Protocol specification states that "authorization is OPTIONAL for MCP implementations. That single word, capitalized in the spec's own text, is the reason a deployment-layer security baseline has to exist independently of the protocol itself. MCP, introduced by Anthropic in late 2024, defines a standardized interface through which AI agents discover and invoke external tools, which makes it the connective tissue between a model and whatever systems that model is allowed to touch. If a protocol does that job but leaves authentication optional across every transport type, every operator is left with a gap the protocol will never close on its own.
The March 2025 specification (version 2025-03-26) formalized OAuth 2.1 as the authentication standard for remote servers, and the November 2025 revision (version 2025-11-25) added mandatory PKCE, OIDC Discovery support, and OAuth Client ID Metadata Documents on top of it. Formalizing a standard is not the same as enforcing one. The stdio transport, still common for local tool integrations, has no authentication mechanism. OAuth 2.1 exists only for HTTP-based transports, and even there, implementing it correctly is left entirely to whoever stands up the server.
That permissiveness runs through three trust boundaries that exist inside every MCP deployment, and the spec makes a meaningful commitment at none of them. The first sits between the LLM and the MCP client, where the model reads tool descriptions it has no way to verify as accurate or unmodified. The second sits between the client and the server, where authentication and response validation are expected but routinely absent or incomplete. The third sits between the server and the downstream systems it acts against, file systems, databases, cloud APIs, where the server operates with permissions that are, in practice, over-scoped far more often than not. Each boundary needs its own enforcement, but the spec leaves all three for someone else to handle.
What the spec's permissiveness enables in practice
The gap is not an abstract design concern. The Cloud Security Alliance's 2026 MCP security guidance found that by early 2026, roughly half of internet-exposed MCP servers had no authentication controls, and between January and February 2026, researchers filed more than 30 CVEs against MCP infrastructure. Several distinct attack classes account for that volume, and each maps to one of the trust boundaries the spec leaves undefended.
Tool poisoning is the attack class native to MCP itself. Servers expose their tools through natural-language descriptions, and the model reads these and treats them as instructions, so the description field works as an execution surface in its own right. A compromised or malicious server can embed redirection logic inside that description, and the agent will carry it out across every session and every user until someone notices. Tool shadowing compounds the problem: because every tool description in a session is visible to the model simultaneously, a poisoned server can override the behavior of tools belonging to a completely different, legitimate server. The CSA guide singles out the boundary between the LLM and the MCP client, precisely where these descriptions get read, as undefended at the protocol level.
A related variant is the rug-pull. An operator approves a server that behaves correctly at review time, but the server can later update its tool descriptions to add exfiltration or redirection logic the agent then follows, because the original trust grant never expires and never gets re-checked. The mechanism needs no access to the host system at all, only the ability to edit a description on the server side.
MCP has also reopened a legacy vulnerability class: command and path injection. CVE-2025-6514, carrying a CVSS score of 9.6, affected the widely used mcp-remote proxy package across more than 437,000 installed environments, and stands as the highest-severity finding from the protocol's early security record. Even Anthropic's own Filesystem MCP reference implementation was found to lack basic traversal defenses, a fact that rules out treating any reference implementation as an inherently safe starting point.
Over-privileged servers turn routine code execution bugs into credential theft. CVE-2026-5058, with a CVSS score of 9.8, is a command-injection bug in a community-maintained MCP server that lets an attacker run arbitrary code in the server's own context. On an EC2 instance, that access can be used to query the metadata service for temporary role credentials. The Smithery platform compromise in October 2025 followed a similar path: a path-traversal flaw in the build configuration let an attacker read arbitrary files from the builder machine, exposing a Fly.io API token that granted code execution across thousands of hosted MCP servers and allowed interception of API keys flowing from thousands of clients. The postmark-mcp npm package, discovered in September 2025, impersonated a legitimate email MCP library and silently copied every outgoing email to an attacker, accumulating downloads before anyone caught it. It stands as the first confirmed malicious MCP server found in the wild.
Supply chain exposure multiplies all of the above. In April 2026, OX Security disclosed a systemic architectural flaw, and it hit a large number of vulnerable instances across a supply chain built on hundreds of millions of package downloads. And on April 3, 2026, Microsoft's own @azure-devops/mcp npm package was found missing an authentication layer on a server handling work items, repositories, and pipelines, letting an attacker reach configuration details, API keys, and authentication tokens without valid credentials of any kind. If a server shipped by Microsoft can ship without that layer, no operator should assume a server is safe because of who built it.
The CIS MCP Server Benchmark establishes the first consensus baseline
On September 16, 2026, the Center for Internet Security released CIS MCP Server Benchmark v1.0.0, giving operators a vendor-neutral, consensus-developed reference to check a deployment against instead of trusting the judgment of whoever built it. The benchmark has 55 prescriptive recommendations spread across 10 security domains, and you can download it for free.
Those 10 domains are Governance and Versioning, Transport and Connectivity, Authentication and Authorization, Client (Host) Configuration, Server Configuration, Data Protection and Privacy, Observability and Audit, Supply Chain Security, Isolation and Execution Safety, and Resource Limits and Caching. Together they cover the full span of an MCP deployment, from how a server identifies itself to how its resource consumption gets bounded at runtime.
The benchmark is deliberately scoped to configuration and operation. It does not solve prompt injection as a general class, does not rate the quality of a model's judgment, and does not remove the obligation to treat agent output as untrusted input no matter how the deployment is configured. It names the domains that have to be covered. It does not, by itself, tell an operator how to cover them.
A domain-by-domain mapping against a representative deployment, one handling deploy, rollback, and secret-reading operations, shows that four of the 10 domains pass by construction on a well-managed platform. Transport and Connectivity is satisfied by HTTPS-only Streamable HTTP paired with a strict Origin allowlist. Governance and Versioning is satisfied by pinning the spec version and versioning tool schemas. Client Configuration is satisfied if you combine an origin allowlist with verified publisher identity. Supply Chain Security is satisfied by pinned dependencies and signed images. Operators running disciplined infrastructure practices inherit these four largely for free.
The remaining six domains do not arrive for free under any circumstances. Authentication and Authorization requires OAuth 2.1 with scopes defined per tool. For Server Configuration, you need least-privilege tool exposure with destructive tools gated behind approval. Data Protection requires secrets redacted from both output and logs. Observability and Audit requires an append-only log of every tool call. Isolation and Execution Safety requires sandboxed tool handlers. For Resource Limits, you need per-tool timeouts, rate limits, and cache isolation between users. Each of these six demands a specific engineering decision that the benchmark can point to but cannot make on an operator's behalf.
Elicitation is one mechanism worth understanding here. The 2026-07-28 spec revision redesigned elicitation semantics so that a server can pause mid-flow, ask the user something, and wait for an answer before proceeding. A benchmark-aligned deployment wires every destructive tool, deploying to production, rolling back a release, rotating a secret, through an elicitation approval, so that no action with real blast radius completes purely on model output.
The six configuration decisions operators must make that the spec and benchmark cannot make for them
The benchmark names the domains that need coverage. Translating each domain into a working configuration is still the operator's job, because the right answer depends on what a given server does and what systems it can reach.
The first decision concerns authentication, and the right shape is OAuth 2.1 with scopes assigned per tool, with one token covering an entire server as the wrong shape. The November 2025 spec makes PKCE mandatory for public clients: you use the Authorization Code grant for human users and Client Credentials for machine-to-machine access. A single bearer token that covers every tool on a server is one confused-deputy incident away from handing over an entire environment, which is exactly the shape the Azure DevOps MCP flaw took, so downstream access should flow through OAuth token exchange, never through token passthrough. Scopes need to be defined per tool, not per server.
The second decision concerns binding and network exposure, specifically where a server listens and what it's permitted to reach. A server should bind to 127.0.0.1, not 0.0.0.0, and the CSA guide identifies binding to all interfaces as the single most common misconfiguration found in the field. Filesystem access should be blocked by default, with read-only access granted only to specific named paths, and outbound network access should be blocked by default with explicitly whitelisted endpoints as the only exception. The Ruflo incident in July 2026 showed what happens without these defaults: its default docker-compose deployment exposed POST /mcp with no authentication, allowing unauthenticated invocation of terminal_execute and exfiltration of provider API keys. The flaw was fixed in version 3.16.3, but the dangerous configuration had been the default setting, not an edge case someone had to opt into.
The third decision concerns tool integrity: maintaining an approved registry and actively detecting changes to it. The model should never be relied on to judge whether a tool description is safe simply by reading it, because that description is the attack surface itself. An approved registry should record server identity, tool name, input schema, allowed side effects, and expected version for every tool in use. The live definition should be compared against that approved record at startup and on every connection, and any change to a high-risk field should halt operation until a human re-approves it. This registry comparison is the structural answer to the rug-pull pattern: the tool description can still change after approval, but the drift gets caught before the agent acts on it.
The fourth decision concerns data protection: secrets and sensitive content must never surface in logs, prompts, or tool output. You should never let session tokens sit in plaintext on disk, in environment variables, or anywhere accessible to other processes. In containerized or serverless environments, tokens should be pulled from dedicated secret stores at the moment of invocation. If tool output contains credentials, you need to redact it before it ever reaches the log store. The Smithery compromise exposed production tokens because secrets had been written into environment files the server itself could read. The Supabase Cursor agent prompt injection from mid-2025 traced back to the same category of error: a service-role key sat inside an agent that processed user-generated content, and the fix is to give any agent handling untrusted input an anon key or a read-only Postgres role instead.
The fifth decision concerns audit logging: what gets captured, and for how long. Every MCP call should be logged with server identity, tool name, argument fingerprint, response size, and verdict. Logs should centralize into an append-only store, with retention matched to the organization's incident response SLA and a minimum duration aligned to internal policy. Logs need enough detail to reproduce a session after the fact, while credentials and other sensitive flagged content get redacted from the record itself. Correlation IDs are what make end-to-end tracing of a request across tools and sessions possible; without them, reconstructing an incident after the fact turns into guesswork. CData's production MCP guidance warns that without continuous monitoring, MCP servers quickly become blind spots inside AI infrastructure.
The sixth decision concerns isolation and resource limits, bounding what any single tool handler can consume or affect. Tool handlers need to run sandboxed, and untrusted tool output must never execute in the same context as the MCP server process itself. CPU and memory quotas should be enforced per execution, with hard timeouts attached. Rate limits need to apply per tool, per user, and per session, not just per server. Cache isolation between users matters just as much: one user's cached tool output should never be readable from another session.
A layered minimum viable posture across all six decisions
None of the six decisions functions as a substitute for the others. A deployment with airtight OAuth scopes and a wide-open bind address is still exposed. A deployment with perfect network isolation and no tool integrity registry is still vulnerable to a rug-pull. The six decisions form a layered structure where each one closes a different trust boundary, and the posture only holds when all six are in place together.
Authentication with per-tool scopes closes the client-to-server boundary, making sure a compromised credential can reach only the tools it was actually scoped for. Binding to localhost and restricting filesystem and network access closes the boundary between the server and the downstream systems it touches, shrinking what's reachable even if authentication somehow fails. A tool integrity registry closes the boundary between the LLM and the MCP client, the one boundary the CSA guide identifies as currently undefended at the protocol level, by catching drift in tool descriptions before the model acts on them. Data protection controls make sure that even if a compromise succeeds at any other layer, it can't yield usable credentials, because secrets never sit in logs, environment files, or plaintext caches. Audit logging doesn't prevent an incident, but it's what turns an incident into something an organization can actually reconstruct and respond to, provided correlation IDs tie the session together end to end. Isolation and resource limits function as the last layer, containing the blast radius of a tool handler that has already been exploited, so a single compromised execution can't exhaust resources, read another user's cache, or run code outside its sandbox.
Assembled this way, the posture maps cleanly onto the CIS benchmark's 10 domains, with the four that a well-managed platform inherits by construction (Transport and Connectivity, Governance and Versioning, Client Configuration, Supply Chain Security) sitting alongside the six that demand the deliberate decisions laid out above. What this layered structure cannot do is resolve whether a given instruction reaching the model, however it arrives, should be trusted. It does not, and was never built to, govern judgment. That line is where the operator's responsibility continues well past anything a spec or a benchmark can specify in advance.


