November 3, 2026
Updated: November 4, 2026
Tool poisoning, token passthrough, rug pulls and more, each with a test and a control.
Abdalla Mohamed

MCP security is the work of protecting the Model Context Protocol connections that let AI applications call tools, read data and act in other systems. The risks that matter most are tool poisoning, indirect prompt injection through tool output, over-broad OAuth scopes, token passthrough, confused deputy flaws, malicious or changed servers, supply chain tampering, exposed local servers, weak sandboxing and thin logging. The official MCP guidance puts most controls on implementers, so the practical answer is to test each risk against a named control before agents reach production data.
This guide is for security engineers, AppSec leads and platform teams who run or approve MCP servers. It uses the current protocol revision, 2026-07-28, and the security guidance on modelcontextprotocol.io as primary sources. Each risk gets its mechanism, a dated real example where one exists, a lab test and the control that closes it. No exploit code is included.
The Model Context Protocol is an open protocol, introduced by Anthropic in November 2024, that standardizes how AI applications connect to external tools and data. It uses JSON-RPC messages and three roles:
Servers run in two common ways. A local server is launched by the client as a subprocess and talks over stdio. A remote server listens on an HTTP endpoint and talks over Streamable HTTP.
One detail changes how you test. Revision 2026-07-28 removed protocol-level sessions from Streamable HTTP. Earlier revisions, up to 2025-11-25, could assign an Mcp-Session-Id, so session hijacking tests apply there. In the current revision, servers that need state mint an explicit handle and receive it back as a tool argument. Before any assessment, record which protocol versions each client and server supports, because many deployments still speak the older revisions.
A traditional API has a fixed caller and fixed inputs. MCP adds a language model that decides which tool to call based on text, and much of that text comes from servers and data sources you do not fully control. A useful way to map MCP risk is by four trust boundaries:

Most serious MCP findings combine two boundaries: untrusted text crosses boundary 2 and steers the model into using privileges at boundary 4. That is why prompt-level defenses alone are not enough, and why least privilege at the server matters as much as model behavior. If you are new to that first half of the problem, our guide to prompt injection attacks explains why models follow injected instructions. For risks that span the whole agent, not only its MCP connections, see our guide to agentic AI security.
Two OWASP projects frame these risks. The OWASP Top 10 for LLM Applications 2025 lists Prompt Injection (LLM01) and Excessive Agency (LLM06), both central to MCP. The newer OWASP MCP Top 10 names MCP-specific risks such as Tool Poisoning (MCP03) and Lack of Audit and Telemetry (MCP08); on 2026-11-04 the project listed itself in "Phase 3 – Beta Release and Pilot Testing," so treat its wording as a draft. Our OWASP LLM Top 10 breakdown covers the model-level list in detail.
The MCP project publishes Security Best Practices alongside the specification. A few requirements carry the most weight for testers:
Authorization itself is optional in MCP. The authorization specification says HTTP-based servers should follow it, while stdio servers should not and should instead read credentials from the environment. In practice, that means many local servers run with whatever secrets sit in their environment, which makes sandboxing and secret scoping part of authorization.
| # | Risk | Trust boundary | Core test | Core control | OWASP MCP Top 10 |
|---|---|---|---|---|---|
| 1 | Tool poisoning | Metadata to model | Review all tool metadata; plant a benign canary instruction in a lab server | Show full descriptions; allowlist and pin servers | MCP03 |
| 2 | Indirect prompt injection via tool output | Output to model | Seed canary instructions in data an agent reads | Treat output as data; confirm sensitive actions; narrow sessions | MCP06 |
| 3 | Over-broad OAuth scopes | Client to server | Compare granted scopes with each tool's real need | Minimal initial scopes and step-up authorization | MCP02 |
| 4 | Token passthrough and weak token validation | Client to server | Present a token issued for another resource | Audience validation; separate downstream tokens | MCP01, MCP07 |
| 5 | Confused deputy in proxy servers | Client to server | Register a second client and check consent per client | Per-client consent, exact redirect URIs, single-use state | MCP07 |
| 6 | Malicious and rug-pull servers | Server to client | Change a lab tool after approval; return unsafe auth URLs | Re-approval on change; URL scheme and IP validation | MCP03, MCP09 |
| 7 | Supply chain tampering | Server to host | Inventory and diff every server package | Pinned versions, integrity checks, internal registry | MCP04 |
| 8 | Exposed local servers | Network to server | Probe bind address, Origin handling and auth | Bind to 127.0.0.1, validate Origin, require auth | MCP07 |
| 9 | Weak sandboxing and command execution | Server to downstream | Path boundary and process privilege tests | Containers, least privilege, no shell interpolation | MCP05 |
| 10 | Missing logging and audit trails | All | Reconstruct a test session from logs | Structured tool-call logs without secrets | MCP08 |

What it is. A server's tool descriptions, parameter descriptions and annotations are text the model reads when deciding what to do. If that text hides instructions, the model may follow them while the user sees only a short tool name. Invariant Labs described this tool poisoning attack on April 1, 2025, showing a harmless-looking tool whose description asked the model to read local configuration and key files. The same post described "shadowing," where a malicious server's description changes how the agent uses a trusted tool from a different server, without the malicious tool ever being called.
How to test it. Pull the full tools/list response from every connected server and review each name, description, input schema and annotation for instruction-like text, hidden characters or references to other tools. Then, in a lab, add a benign canary instruction to a test server's description, such as asking the model to append a harmless marker word to its reply. Check two things: whether the host shows the full description to the user before approval, and whether the model obeys the canary. If it obeys a harmless instruction, it can obey a harmful one.
Control. Show users the complete tool definition, not a summary. Allow only reviewed servers, pin their versions and hash their tool definitions. The tools specification requires clients to treat annotations as untrusted unless they come from trusted servers. Keep a human approval step for any tool that sends, writes or deletes.
What it is. Tool results flow back into the model's context. When a tool reads content an outsider can write, such as an issue, email, web page or document, that outsider can plant instructions the agent may follow. On May 26, 2025, Invariant Labs showed an agent using the GitHub MCP server reading a malicious issue in a public repository, pulling data from the owner's private repositories and publishing it in a public pull request. The researchers stressed that this was not a flaw in the GitHub MCP server code but an architectural problem at the agent level.
How to test it. In a test tenant, seed canary instructions in data sources the agent reads, for example a test ticket that asks the agent to add a marker comment in a different project. Run normal user tasks and observe whether the agent takes actions outside the task, crosses repository or tenant boundaries, or calls write tools without a confirmation prompt. Record whether "always allow" settings remove the human check.
Control. The tools specification says clients should validate tool results before passing them to the model and show tool inputs to the user before calling the server. Split read and write tools, require confirmation for writes, and restrict each session to the smallest data scope, such as one repository. Treat model alignment as one layer, not the boundary.
What it is. An MCP server that requests every scope up front turns any token leak or injected instruction into broad access. The MCP guidance on scope minimization describes a stolen token carrying scopes such as files:* or admin:* that were granted because the server listed every scope and the client requested them all. It also flags a quieter mistake: treating the scopes claimed in a token as sufficient without server-side authorization logic.
How to test it. Compare scopes_supported in the protected resource metadata, the scope values in WWW-Authenticate challenges and the scopes on issued tokens with what each tool actually needs. Call privileged tools with a token that lacks the needed scope and confirm a 403 with an insufficient_scope challenge. Then confirm the server checks the user's own permissions for the specific object, not just the scope string. Our OAuth security guide covers the underlying flows.
Control. Start with a minimal scope set for discovery and read operations, and request more through step-up authorization when a privileged tool is first used. Avoid wildcard or omnibus scopes, and log every elevation event with a correlation ID.
What it is. Token passthrough is an anti-pattern where an MCP server accepts a token without checking it was issued for that server and forwards it to a downstream API. The authorization specification forbids it: servers must validate that tokens were issued specifically for them as the audience, and must not accept or transit any other tokens. Passthrough breaks rate limits and audit trails that depend on the token audience, and lets a stolen token for one service unlock another. The same family includes state handles in the current revision: the security guidance says servers must not treat possession of a state handle as authentication.
How to test it. Using test identities, request a token for a different resource from the same authorization server and present it to the MCP server; the server should return 401. Check whether the token sent downstream is the client's token or a separate token the server obtained. Confirm tokens never appear in query strings or logs. For stateful tools, try a handle created by one test user from another test user's session; the server should refuse.
Control. Validate issuer, audience and expiry on every request, following RFC 8707 resource indicators. Obtain separate downstream tokens for the server's own calls. Generate handles with a secure random generator, bind them to the authenticated user server-side and expire them.
What it is. A confused deputy is a privileged program tricked into misusing its authority. In MCP, the official guidance describes it for proxy servers that front a third-party API. The attack needs four conditions: the proxy uses a static client ID with the third-party authorization server, it lets MCP clients register dynamically, the third-party server sets a consent cookie, and the proxy does not collect its own per-client consent. An attacker registers a client with their own redirect URI, sends the victim a link, the consent cookie skips the consent screen and the authorization code lands with the attacker.
How to test it. In staging, complete a normal authorization with a test user. Register a second test client with a different redirect URI and start a new flow. The proxy should show its own consent page naming the new client, the scopes and the redirect URI. Also check that redirect URIs match exactly, that the state value is single-use and short-lived, and that the consent page cannot be framed.
Control. Keep a per-user registry of approved client IDs and check it before forwarding to the third party. Use exact string matching for redirect URIs, set consent cookies with the __Host- prefix and Secure, HttpOnly and SameSite=Lax, and block framing with frame-ancestors or X-Frame-Options: DENY.
What it is. A server you connect to can attack you in two ways. A rug pull is a server whose tool definitions change after you approved them; Invariant Labs noted that a malicious server "can change the tool description after the client has already approved it."
A client-side attack abuses data the server sends during setup. CVE-2025-6514 is a real case: mcp-remote, a widely used proxy for connecting local clients to remote servers, was exposed to OS command injection when connecting to an untrusted server through a crafted authorization_endpoint URL. The GitHub advisory lists versions 0.0.5 up to but not including 0.1.16 as affected, with 0.1.16 fixed; the CNA, JFrog, scored it 9.6 (CVSS 3.1).
The security guidance also warns that a malicious server can point OAuth discovery URLs at internal addresses such as cloud metadata endpoints, turning the client into a server-side request forgery (SSRF) proxy.
How to test it. In a lab, approve a test server, then change one tool description and send a list-changed notification. The client should flag the change and ask again. Point the client at a lab server that returns an authorization URL with a non-HTTP scheme, and another whose metadata points to a private IP address. The client should reject both without opening a shell or making the internal request.
Control. Re-prompt on any tool definition change and alert on hash mismatches. Accept only https authorization URLs (and http only for loopback during development), never open URLs through a shell, block private and link-local ranges for OAuth discovery, and route server-side clients through an egress proxy. Keep mcp-remote and similar bridges patched.
What it is. Most MCP servers install from public package registries, often through commands that fetch the latest version at launch. That makes every update a trust decision. In September 2025, researchers found postmark-mcp, an npm package that copied a legitimate Postmark email library. According to The Hacker News, version 1.0.16, released September 17, 2025, added one line that blind-copied every outgoing email to an attacker-controlled address; the package had 1,643 downloads before its author removed it. Postmark said it had no involvement with the package. Researchers described it as the first malicious MCP server seen in the wild.
How to test it. Build an inventory of every MCP server on developer machines, CI runners and production hosts, including transitive dependencies. Flag configs that pull unpinned or latest versions at launch, servers from unverified publishers and servers nobody approved (OWASP calls these "shadow MCP servers," MCP09). Diff the code between the approved version and the installed one. Our overview of supply chain attacks covers the wider pattern.
Control. Pull servers from an internal allowlisted registry, pin exact versions with integrity hashes, review diffs before upgrades and restrict outbound network access so a tampered server cannot reach arbitrary hosts.
What it is. Local servers and developer tools often listen on HTTP ports without authentication, on the assumption that only the local user can reach them. Browsers break that assumption. CVE-2025-49596 affected MCP Inspector, the project's own debugging tool: versions below 0.14.1 lacked authentication between the Inspector client and its proxy, which let unauthenticated requests launch MCP commands over stdio. The GitHub CNA scored it 9.4 (CVSS 4.0). Oligo Security, which reported it, described a browser-based path and said the fix added a session token and Host and Origin checks.
How to test it. On a standard developer workstation image, list listening ports and check which MCP servers bind to 0.0.0.0 instead of 127.0.0.1. Send a request with a foreign Origin header; the Streamable HTTP specification requires a 403. Send an unauthenticated request and confirm rejection.
Control. Follow the Streamable HTTP security rules: validate Origin, bind local servers to 127.0.0.1 and authenticate every connection. Prefer stdio for local-only servers, or Unix domain sockets with restricted access.
What it is. A local MCP server runs with the same privileges as the client that launched it, so a bug or a malicious instruction can reach everything the user can. Path checks are a common weak point. The official filesystem server had two such flaws, CVE-2025-53109 and CVE-2025-53110: versions before 0.6.4 or 2025.7.01 could allow access to unintended files through symlinks inside allowed directories, or when a path prefix matched an allowed directory. Command injection in server code that builds shell commands from tool arguments is the other recurring pattern (OWASP MCP05).
How to test it. In a lab with an allowed directory, test boundary cases: a symlink pointing outside it, and a sibling directory whose name shares the allowed prefix. Review server code for shell calls built from arguments. Check which user the server runs as, which files and secrets it can read, and whether it has network access it does not need.
Control. Run servers in containers or OS sandboxes with minimal file system and network access, pass arguments as arrays rather than shell strings, resolve real paths before checking boundaries, and grant extra privileges explicitly. For one-click installs, the security guidance requires showing the exact command and getting approval first.
What it is. If a tool call cannot be traced to a user, a client, a server version and an approval decision, incidents become guesswork. OWASP lists Lack of Audit and Telemetry as MCP08, and the tools specification says clients should log tool usage for audit purposes. Token passthrough makes this worse, because downstream logs then show the wrong identity.
How to test it. Run a scripted session in staging that includes a denied call, an approved write and a scope elevation. Then try to reconstruct it from logs alone. Check that secrets and full tokens never appear.
Control. Log these fields for every tool call:
| Field | Why it matters |
|---|---|
| Timestamp and correlation ID | Join host, client, server and downstream logs |
| User and client identity | Attribute the action to a person and an application |
| Server name, version and tool definition hash | Detect rug pulls and unapproved servers |
| Tool name and argument summary | Reconstruct intent without storing secrets |
| Approval decision | Show whether a human confirmed it |
| Scopes requested and granted | Spot elevation and over-broad access |
| Result status and downstream target | Trace impact |
An MCP assessment combines API testing, OAuth review, application code review and model-in-the-loop testing. A practical sequence:

Use a matrix like this to keep evidence consistent:
| Area | What to check | Evidence to collect | Pass condition |
|---|---|---|---|
| Tool metadata | Full tools/list output, hashes, display in host | Saved responses and screenshots of approval dialogs | Full text shown; changes trigger re-approval |
| Injection handling | Canary in descriptions and in data sources | Conversation transcripts and tool-call logs | No unconfirmed write or cross-boundary action |
| Token handling | Audience, issuer, expiry, passthrough | Request and response pairs with tokens redacted | Foreign-audience tokens get 401; no passthrough |
| Scopes | Granted scopes against tool needs | Token claims and challenge headers | Minimal initial scopes; step-up for privileged tools |
| Consent and redirects | Per-client consent, exact redirect match, state | Flow captures from staging | Consent shown per client; mismatches rejected |
| Client URL handling | Scheme allowlist, private IP blocking | Lab server responses and client behavior | Unsafe URLs rejected; no shell launch |
| Local exposure | Bind address, Origin, authentication | Port listings and responses | Loopback only; foreign Origin gets 403 |
| Sandbox | Path boundaries, run-as user, egress | Test results and process details | No access outside allowed paths or networks |
| Supply chain | Versions, pins, publishers, diffs | Inventory and diff output | All servers approved and pinned |
| Logging | Required fields, secret redaction | Log extracts | Session reconstructable; no secrets logged |
Automated scanners can flag known-vulnerable packages and suspicious tool descriptions, but they cannot judge whether a tool's privileges fit its purpose or whether a chain of harmless-looking calls adds up to data exposure. That judgment is the core of a manual assessment.
For server builders
For host and client builders
For security teams
MCP security is the set of controls that protect Model Context Protocol connections between AI applications and the tools and data they use. It covers tool metadata and output entering the model's context, authorization between clients and servers, the trustworthiness of server code and the privileges servers hold in downstream systems.
The protocol defines security requirements, but most protections depend on how clients and servers implement them. Authorization is optional in MCP, local servers run with the launching user's privileges and models can follow injected text. An MCP deployment is as secure as its token validation, consent, sandboxing, approvals and logging.
The main considerations are tool poisoning, indirect prompt injection through tool output, scope minimization, token audience validation and the ban on token passthrough, confused deputy risks in proxy servers, malicious or changed servers, supply chain integrity, local server exposure, sandboxing and audit logging.
Tool poisoning is hiding instructions in an MCP tool's description or schema so the model follows them while the user sees only a short tool name. Invariant Labs described it in April 2025. Defenses include showing full tool definitions, pinning reviewed servers and requiring approval for sensitive actions.
Authorize and scope the test, inventory clients, servers and tools, then test token handling, scopes, consent, client URL handling, local exposure, sandbox boundaries and logging. Add model-in-the-loop tests that use harmless canary instructions in tool metadata and data sources, and retest each fix.
No. Authorization is optional. When used, HTTP-based servers should follow the MCP authorization specification, which builds on OAuth 2.1 and requires RFC 8707 resource indicators. Stdio servers should not use that flow and should read credentials from the environment instead.
MCP turns an AI model into an operator with real credentials, so the questions that matter are the old ones: who can reach the tool, which token it uses, what it can touch and whether anyone would notice. Run the ten tests above against your own deployment and record which control answers each one.
When you want an independent assessment, DeepStrike's LLM and AI application penetration testing covers prompt injection, data leakage and access controls in AI applications. Tell us which MCP servers and tools your application uses so they can be included in scope, or contact DeepStrike to talk it through.
Abdalla leads offensive security engagements at DeepStrike, specializing in web and API penetration testing, Active Directory attack paths, and cloud misconfiguration exploitation. His writing translates findings from live engagements into fixes security teams can ship the same week.

Stay secure with DeepStrike penetration testing services. Reach out for a quote or customized technical proposal today
Contact Us