MCP security

Secure and govern
HoneyHive Engineering

MCP security covers the attacks on MCP servers and clients, from tool poisoning to token passthrough, and the controls the spec and OWASP list for each.

MCP security is the set of controls that keep a Model Context Protocol connection from being abused. Two kinds of risk meet in it. Classic web risks (OAuth mistakes, request forgery, over-broad tokens) are documented in the spec’s security best practices. Model-side risks, where text in a tool description or result steers the model, are documented by researchers such as Invariant Labs. For what the protocol is, see Model Context Protocol.

All spec statements below come from revision July 2026.

Where the risk sits

The spec’s own list is aimed at “developers implementing MCP authorization flows, MCP server operators, and security professionals” (security best practices). Who has to act depends on the attack:

Attack Who must defend Core control, per the source
Confused deputy MCP proxy server operators Per-client consent before forwarding to the third-party authorization server, and exact redirect_uri matching (spec)
Token passthrough Server authors Servers MUST NOT accept tokens not explicitly issued for the MCP server (spec)
SSRF Client builders, and authorization servers that fetch client metadata Require HTTPS, block private and link-local ranges, validate redirect targets, consider an egress proxy (spec)
State handle hijacking Server authors MUST NOT treat possession of a handle as authentication; bind handles to the verified user (spec)
Local server compromise Client builders, then users Show the exact startup command, require approval, sandbox (spec)
Malicious authorization URL Client builders Allow only http and https; reject javascript:, data:, file:, vbscript:; never open URLs through a shell (spec)
Mix-up attack Client builders Validate iss on the authorization response. The spec says PKCE alone does not prevent it (spec)
Over-broad scopes Server authors and client builders Minimal initial scopes, step up through WWW-Authenticate challenges (spec)

The attacks in more detail

Confused deputy

The spec says this needs all four conditions at once: a proxy (the role an MCP gateway plays) that uses a static client ID with a third-party authorization server, dynamic client registration, a consent cookie set after the first authorization, and no per-client consent in the proxy. With all four, an attacker can register a client with their own redirect_uri, send the user a link, and receive an authorization code because the consent screen is skipped (spec). Removing any one condition breaks the chain, but the spec’s requirement is the consent step.

Token passthrough

This is the case where a server accepts a token from a client and forwards it downstream without checking it was issued to that server. The spec lists lost control (rate limits and monitoring tied to the token audience get bypassed), weak audit trails and broken trust boundaries as the harms. The authorization spec adds that servers MUST validate the token’s audience and “MUST NOT accept or transit any other tokens” (authorization spec).

SSRF

A malicious MCP server controls several URLs the client later fetches during OAuth discovery, such as resource_metadata and the token endpoint. The spec’s examples include the 169.254.169.254 cloud metadata address, localhost services, DNS rebinding and redirect chains (spec). It warns against hand-written IP validation, because attackers use encodings (octal, hex, IPv4-mapped IPv6) that custom parsers miss.

State handle hijacking

This revision of MCP has no protocol-level sessions. A server that needs state across calls mints a handle (the spec’s examples are a shopping cart ID or a workflow ID) and takes it back as a tool argument. If the server does not check that the handle belongs to the caller, anyone who guesses it acts on that user’s state (spec). Servers on protocol version November 2025 or earlier use server-assigned session IDs, and the spec points to the older version of its page for those.

Local server compromise

A local server runs on the user’s machine with the client’s privileges. The spec names three routes: a malicious startup command in a client configuration, a payload inside the server, and an insecure server left running on localhost and reached by DNS rebinding. Its example commands are an npx install followed by a curl upload of ~/.ssh/id_rsa, and a sudo rm -rf (spec).

The stdio transport is not the problem. The spec states it “is not inherently vulnerable”, and flags only proxy designs that spawn servers as child processes, where a client-side XSS bug can become code execution.

Tool poisoning, shadowing and rug pulls

Invariant Labs published the tool poisoning write-up on 1 April 2025, so it predates the current spec. Its definition is malicious instructions in a tool description, invisible to users but visible to the model. In its demonstration, an add tool’s description told the agent to read ~/.cursor/mcp.json and SSH keys and send them in a sidenote parameter, and Cursor leaked the files while the user saw a simplified tool name. In a second demonstration a malicious server’s description shadowed a trusted email tool, and the Cursor agent sent all emails to the attacker even when the user named a different recipient (Invariant Labs).

The same post describes the rug pull: “a malicious server can change the tool description after the client has already approved it.” Its suggested mitigations are showing full tool descriptions to users, pinning tools by hash or checksum so changes are detected, and stricter data-flow boundaries between servers.

Since then, the OWASP MCP Top 10 lists Tool Poisoning as MCP03:2025. The project page marks the list as beta, with no version or release date shown. Tool poisoning is a case of indirect prompt injection, which the protocol cannot fix by itself. The spec overview says MCP “cannot enforce these security principles at the protocol level”, and the model reads descriptions and results as text.

OWASP MCP Top 10 at a glance

All items are tagged 2025 on the OWASP project page, where the list is in beta:

ID Name
MCP01 Token Mismanagement & Secret Exposure
MCP02 Privilege Escalation via Scope Creep
MCP03 Tool Poisoning
MCP04 Software Supply Chain Attacks & Dependency Tampering
MCP05 Command Injection & Execution
MCP06 Prompt Injection via Contextual Payloads
MCP07 Insufficient Authentication & Authorization
MCP08 Lack of Audit and Telemetry
MCP09 Shadow MCP Servers
MCP10 Context Injection & Over-Sharing

Controls the MCP spec asks for on every tool call

Beyond the attack list, the tools spec says there SHOULD always be a human in the loop who can deny tool invocations, and that clients MUST treat tool annotations as untrusted unless they come from a trusted server. Servers MUST validate inputs, apply access controls, rate limit and sanitize outputs. Clients SHOULD show tool inputs before the call, validate results before the model sees them, set timeouts and log usage for audit.

Authorization is optional in MCP. HTTP-based servers should follow the authorization spec, which requires OAuth 2.1 on the authorization server, Resource Indicators (RFC 8707) with a resource parameter on both authorization and token requests, and no access tokens in the URI query string. A stdio server should instead take credentials from the environment.

A checklist by role

This is a summary of the requirements above, not an extra standard.

Role Do
Server author Validate token audience. Never forward tokens you did not issue. Check handle ownership on every call. Publish minimal scopes. Validate inputs and sanitize outputs.
Client or host builder Show full tool descriptions and inputs. Block private IP ranges and non-HTTP schemes on OAuth URLs. Show the exact command for local server setup and sandbox it. Validate iss. Log tool usage.
Team installing servers Treat a local server as code running with your privileges. Review the startup command. Pin tool definitions where the client allows it, so a rug pull shows up as a change. Keep an inventory, since OWASP lists unmanaged servers as MCP09 Shadow MCP Servers.

Runtime filtering of tool inputs and outputs is covered in AI guardrails and agent guardrails, and attacking a deployed agent on purpose to find these gaps in AI red teaming.

Watching MCP calls in production

The OWASP list includes MCP08 Lack of Audit and Telemetry, and the spec asks clients to log tool usage. One way to get that record is tracing. HoneyHive’s MCP tracing guide covers Python servers and clients: it marks OpenInference auto-instrumentation as experimental and recommends the @trace decorator for production, with enrich_span to add tool name, arguments and results. Any tracing or logging stack that records tool name, arguments and result per call serves the same purpose. For how tool calls sit inside a whole agent run, see agent observability.

FAQ

What are the main MCP security risks?

The MCP spec lists confused deputy, token passthrough, SSRF, state handle hijacking, local server compromise, OAuth URL injection, mix-up attacks and over-broad scopes. Tool poisoning, named by Invariant Labs, is the best-known attack on the model side, and the OWASP MCP Top 10 lists it as MCP03:2025.

What is MCP tool poisoning?

Invariant Labs defines it as malicious instructions embedded in MCP tool descriptions that are "invisible to users but visible to AI models." It is a form of indirect prompt injection (Invariant Labs).

Is a local stdio MCP server safer than a remote one?

The spec advises servers meant to run locally to use stdio to limit access to the client, and says stdio is not inherently vulnerable (security best practices). A local server still runs with the client's privileges, so the spec also asks clients to show the exact startup command and sandbox it.

Does MCP require OAuth?

No. Authorization is optional. HTTP-based transports should follow the authorization spec, and stdio implementations should instead take credentials from the environment (authorization spec).

Share