MCP Security Risks: Threat Model, Attack Vectors, and Defense-in-Depth
TL;DR — MCP security risks: tool poisoning, prompt injection, cross-server exfiltration, rug-pull, confused deputy. Arxiv: "Tool poisoning — malicious instructions in tool metadata — most prevalent client-side vulnerability. STRIDE/DREAD threat modeling across 5 components. Multi-layered defense: static analysis, decision path tracking, anomaly detection, user transparency." OWASP: "Tool poisoning is indirect prompt injection. Tools look normal but responses contain hidden instructions. Trust gap between connect-time and runtime. Isolate privileged tools, enforce server-side, require user confirmation." Survey: "GitHub exploit (May 2025), WhatsApp exfiltration (April 2025), CVE-2025-6514 CVSS 9.6, Smithery breach (October 2025). MCPLib documented 31 attack methods with 70%+ success rates." Schneider: "Defense in depth: sandboxing, authorization boundaries, tool integrity, runtime monitoring. Treat tool descriptions as code. MCP security is architectural — cannot be bolted on." Arxiv: "Three protocol-level vulnerabilities: no capability attestation, bidirectional sampling without origin auth, implicit trust propagation. MCPSec reduces attacks from 52.8% to 12.4%." Learn more with MCP guide, MCP auth, MCP transports, and build MCP server.
Arxiv provides the threat model: "The Model Context Protocol has rapidly emerged as a universal standard for connecting AI assistants to external tools and data sources. While MCP simplifies integration, it introduces significant security vulnerabilities, particularly on the client side. Tool poisoning — where malicious instructions are embedded in tool metadata — as the most prevalent and impactful client-side vulnerability."
Schneider states the core principle: "MCP security is an architectural concern. It can't be bolted on after deployment. Treat tool descriptions as code."
MCP Security Threat Model
user intent vs AI interpretation"] TB2["Boundary 2: Client ↔ MCP Servers
tool descriptions enter model context
TOOL POISONING occurs here"] TB3["Boundary 3: Servers ↔ Downstream
databases, APIs, file stores
CONFUSED DEPUTY occurs here"] end subgraph Attacks["Attack Vectors"] TP["Tool Poisoning
malicious instructions in
tool metadata and responses"] PI["Prompt Injection
indirect injection via
tool responses"] CSE["Cross-Server Exfiltration
malicious server manipulates
legitimate server tools
via shared context"] RP["Rug-Pull Attacks
server silently substitutes
malicious tool versions
after one-time approval"] CD["Confused Deputy
server tricked into
accessing resources on
attacker behalf"] SC["Supply-Chain Attacks
CVE-2025-6514 CVSS 9.6
mcpremote OAuth proxy
437K+ downloads"] ZC["Zero-Click Attacks
Jira, Google Docs
auto-execute without
user interaction"] TS["Tool Shadowing
malicious server alters
other servers tool behavior
31 methods, 70%+ success"] end subgraph Defense["Defense-in-Depth Architecture"] L1["Layer 1: Sandboxing
filesystem isolation
network isolation
process isolation"] L2["Layer 2: Authorization
least privilege
OAuth scopes
server-side enforcement"] L3["Layer 3: Tool Integrity
pre-deployment scanning
tool pinning
version verification"] L4["Layer 4: Runtime Monitoring
behavioral anomaly detection
decision path tracking
user transparency"] end TB2 --> TP TB2 --> PI TB2 --> CSE TB2 --> TS TB2 --> RP TB3 --> CD TB1 --> ZC TB2 --> SC TP --> Defense PI --> Defense CSE --> Defense RP --> Defense CD --> Defense SC --> Defense ZC --> Defense TS --> Defense L1 --> L2 --> L3 --> L4
Attack Vector Comparison
| Attack | Target | Vector | Impact | Real Incident |
|---|---|---|---|---|
| Tool Poisoning | LLM context | Malicious tool metadata/responses | Data exfiltration, restricted tool calls | OWASP documented |
| Cross-Server Exfiltration | Shared context | Malicious server manipulates legitimate tools | Data theft via legitimate channels | WhatsApp exploit (Apr 2025) |
| Rug-Pull | Tool definitions | Server changes tools after approval | Silent substitution of malicious tools | Documented pattern |
| Confused Deputy | Server | Server tricked into accessing resources | Unauthorized data access | SSRF via internal URLs |
| Supply-Chain | Client/Server | Vulnerable package | Remote code execution | CVE-2025-6514 (CVSS 9.6) |
| Zero-Click | Agent | Auto-executed malicious content | No user interaction needed | Jira, Google Docs (2025) |
| Tool Shadowing | Other servers | Malicious server alters tool behavior | 70%+ success rate | MCPLib 31 methods |
Defense-in-Depth Layers
| Layer | What It Does | Key Controls | Example |
|---|---|---|---|
| Sandboxing | Isolate server execution | Filesystem, network, process isolation | Container with restricted paths |
| Authorization | Enforce least privilege | OAuth scopes, server-side access controls | Read-only DB user, scoped tokens |
| Tool Integrity | Verify tool trustworthiness | Pre-deployment scanning, tool pinning | Hash verification, version lock |
| Runtime Monitoring | Detect anomalous behavior | Decision path tracking, anomaly detection | Alert on unexpected tool calls |
Implementation
from dataclasses import dataclass
from typing import Optional
from enum import Enum
class AttackVector(Enum):
TOOL_POISONING = "tool_poisoning"
PROMPT_INJECTION = "prompt_injection"
CROSS_SERVER_EXFIL = "cross_server_exfiltration"
RUG_PULL = "rug_pull"
CONFUSED_DEPUTY = "confused_deputy"
SUPPLY_CHAIN = "supply_chain"
ZERO_CLICK = "zero_click"
TOOL_SHADOWING = "tool_shadowing"
class DefenseLayer(Enum):
SANDBOXING = "sandboxing"
AUTHORIZATION = "authorization"
TOOL_INTEGRITY = "tool_integrity"
RUNTIME_MONITORING = "runtime_monitoring"
@dataclass
class MCPSecurityGuide:
"""MCP security risks and defense-in-depth guide."""
def get_threat_model(self) -> dict:
"""STRIDE threat model for MCP."""
return {
"framework": "STRIDE + DREAD",
"components": [
"MCP Host + Client",
"LLM",
"MCP Server",
"External Data Stores",
"Authorization Server",
],
"stride": {
"Spoofing": (
"Malicious server impersonates "
"legitimate server"
),
"Tampering": (
"Tool responses tampered with "
"to inject instructions"
),
"Repudiation": (
"Actions taken via injected "
"instructions hard to trace"
),
"Information_Disclosure": (
"Cross-server exfiltration "
"leaks sensitive data"
),
"Denial_of_Service": (
"Malicious server overwhelms "
"context or resources"
),
"Elevation_of_Privilege": (
"Injected instructions cause "
"agent to use privileged tools"
),
},
"key_finding": (
"Tool poisoning is the most "
"prevalent and impactful "
"client-side vulnerability"
),
}
def get_attack_vectors(self) -> dict:
"""MCP attack vectors with details."""
return {
"tool_poisoning": {
"description": (
"Malicious instructions embedded "
"in tool metadata (descriptions, "
"parameters, responses)"
),
"root_cause": (
"Trust gap between connect-time "
"and runtime: tool descriptions "
"reviewed once at connect, but "
"tool responses go straight into "
"LLM context with no check"
),
"flow": [
"Attacker runs malicious MCP server",
"Tools appear normal at connect time",
"Agent calls tool",
"Response contains hidden instructions",
"LLM follows injected instructions",
"Agent calls restricted tools or "
"exfiltrates data",
],
},
"cross_server_exfiltration": {
"description": (
"Malicious server manipulates "
"legitimate server tools via "
"shared context window"
),
"example": (
"WhatsApp exploit (April 2025): "
"malicious 'random fact' server "
"injected instructions causing "
"agent to use WhatsApp send_message "
"to exfiltrate entire chat history"
),
"key": (
"Malicious server never called "
"directly — attack operates "
"purely through context "
"contamination"
),
},
"rug_pull": {
"description": (
"Server silently substitutes "
"malicious tool versions after "
"one-time approval"
),
"exploit": (
"Most MCP clients perform tool "
"approval as one-time event, "
"allowing servers to change "
"tools afterward"
),
},
"confused_deputy": {
"description": (
"Server tricked into accessing "
"resources on attacker behalf"
),
"example": (
"Server tricked into passing "
"internal URL (e.g., "
"http://169.254.169.254) to "
"access cloud metadata"
),
},
"supply_chain": {
"description": (
"Vulnerabilities in MCP packages"
),
"cve_2025_6514": (
"CVSS 9.6 — OS command injection "
"in mcpremote (most popular OAuth "
"proxy, 437K+ downloads). Malicious "
"server could achieve RCE by "
"injecting crafted OAuth endpoint "
"into system shell"
),
"smithery_breach": (
"October 2025 — path-traversal "
"vulnerability exfiltrated Fly.io "
"API token controlling 3,000+ "
"applications"
),
},
"tool_shadowing": {
"description": (
"Malicious server alters behavior "
"of other servers tools"
),
"mcplib": (
"31 distinct attack methods "
"including Shadow Attacks, "
"Malicious Tool Coverage, "
"Tool Preference Manipulation. "
"Success rates above 70%"
),
},
}
def get_defense_in_depth(self) -> dict:
"""Defense-in-depth architecture."""
return {
"principle": (
"Treat tool descriptions as code. "
"MCP security is architectural — "
"cannot be bolted on after deployment."
),
"layer_1_sandboxing": {
"what": (
"Isolate server execution "
"environment"
),
"controls": [
"Filesystem isolation — prevent "
"access to sensitive files outside "
"granted paths",
"Network isolation — prevent "
"exfiltration to attacker servers",
"Process isolation — minimal "
"privileges, not host user",
],
"client_side": (
"CVE-2025-6514 demonstrated "
"command injection targeting MCP "
"client. Run clients in sandboxed "
"environments (containers, VMs, "
"restricted shell access)"
),
},
"layer_2_authorization": {
"what": (
"Enforce least privilege at "
"tool execution layer"
),
"controls": [
"OAuth scopes for tool-level "
"permissions",
"Server-side access controls — "
"do NOT rely on system prompt",
"Read-only database users",
"Scoped API tokens",
"MiniScope framework — formal "
"permission hierarchies over "
"tool calls based on OAuth scopes",
],
"key": (
"Authorization layer, not LLM "
"reasoning, is appropriate target "
"for formal methods"
),
},
"layer_3_tool_integrity": {
"what": (
"Verify tool trustworthiness "
"before and during use"
),
"controls": [
"Pre-deployment scanning — static "
"metadata analysis",
"Tool pinning — lock tool versions",
"Hash verification — detect "
"tampering",
"Version verification — detect "
"rug-pull attacks",
],
},
"layer_4_runtime_monitoring": {
"what": (
"Detect anomalous behavior during "
"execution"
),
"controls": [
"Behavioral anomaly detection — "
"unexpected tool call patterns",
"Model decision path tracking — "
"trace why LLM called a tool",
"User transparency — show user "
"what tools are called and why",
"Explicit user confirmation for "
"sensitive operations",
],
},
}
def get_protocol_vulnerabilities(self) -> dict:
"""Protocol-level vulnerabilities from research."""
return {
"source": (
"First rigorous security analysis of "
"MCP specification"
),
"vulnerabilities": [
{
"name": "No capability attestation",
"description": (
"Servers can claim arbitrary "
"permissions without verification"
),
},
{
"name": "Bidirectional sampling "
"without origin auth",
"description": (
"Server-side prompt injection "
"via sampling requests"
),
},
{
"name": "Implicit trust propagation",
"description": (
"Multi-server configurations "
"propagate trust implicitly"
),
},
],
"impact": (
"MCP architectural choices amplify "
"attack success rates by 23-41% "
"compared to equivalent non-MCP "
"integrations"
),
"solution": (
"MCPSec protocol extension adds "
"capability attestation and message "
"authentication, reducing attack "
"success from 52.8% to 12.4% with "
"8.3ms median latency overhead"
),
}
def get_owasp_mitigations(self) -> dict:
"""OWASP mitigations for tool poisoning."""
return {
"isolate_privileged_tools": (
"Run high-privilege tools (file access, "
"database, internal APIs) in separate "
"agent context that external MCP "
"servers cannot reach. Apply least "
"privilege."
),
"enforce_server_side": (
"Do not rely on system prompt "
"instructions to restrict tool "
"access. Implement access controls "
"at tool execution layer so injected "
"instructions cannot override them."
),
"user_confirmation": (
"Require explicit user confirmation "
"for sensitive operations. Before "
"agent executes destructive or "
"data-exfiltrating actions, prompt "
"user for approval outside LLM context."
),
"validate_responses": (
"Tool responses should be validated "
"or sanitized before being added to "
"LLM context. Currently responses go "
"straight into context with no check."
),
"separate_privilege_levels": (
"Internal and external tools should "
"not share the same privilege level. "
"A response from untrusted external "
"server should not trigger calls to "
"trusted internal tools."
),
}
MCP Security Checklist
- [ ] MCP introduces significant security vulnerabilities, particularly on the client side
- [ ] Tool poisoning is the most prevalent and impactful client-side vulnerability
- [ ] Tool poisoning: malicious instructions embedded in tool metadata (descriptions, parameters, responses)
- [ ] Root cause: trust gap between connect-time (reviewed once) and runtime (no check on responses)
- [ ] Tool responses go straight into LLM context with no equivalent validation as tool descriptions
- [ ] STRIDE threat model: Spoofing, Tampering, Repudiation, Information Disclosure, DoS, Elevation of Privilege
- [ ] DREAD framework: Damage, Reproducibility, Exploitability, Affected Users, Discoverability
- [ ] Five components: MCP Host+Client, LLM, MCP Server, External Data Stores, Authorization Server
- [ ] Three trust boundaries: User↔Client, Client↔Servers, Servers↔Downstream
- [ ] Cross-server exfiltration: malicious server manipulates legitimate server tools via shared context
- [ ] WhatsApp exploit (April 2025): malicious server exfiltrated entire chat history via legitimate WhatsApp tool
- [ ] GitHub MCP exploit (May 2025): crafted GitHub issue caused agent to access private repos and exfiltrate data
- [ ] Supabase/Cursor exploit (June 2025): malicious SQL in support ticket executed with service-role access
- [ ] Zero-click attacks: Jira and Google Docs MCP servers — malicious content auto-executed without user interaction
- [ ] CVE-2025-6514 (CVSS 9.6): OS command injection in mcpremote OAuth proxy, 437K+ downloads, remote code execution
- [ ] Smithery breach (October 2025): path-traversal exfiltrated Fly.io API token controlling 3,000+ applications
- [ ] Rug-pull attacks: server silently substitutes malicious tool versions after one-time approval
- [ ] Tool shadowing: MCPLib documented 31 attack methods with 70%+ success rates
- [ ] Confused deputy: server tricked into accessing resources on attacker behalf (e.g., internal URLs)
- [ ] Supply-chain attacks: vulnerable packages in MCP ecosystem
- [ ] Protocol-level vulnerabilities: no capability attestation, bidirectional sampling without origin auth, implicit trust propagation
- [ ] MCP architectural choices amplify attack success rates by 23-41% compared to non-MCP integrations
- [ ] MCPSec extension: capability attestation + message authentication reduces attacks from 52.8% to 12.4% (8.3ms overhead)
- [ ] Defense-in-depth principle: treat tool descriptions as code
- [ ] MCP security is architectural — cannot be bolted on after deployment
- [ ] Layer 1 — Sandboxing: filesystem isolation (restrict to granted paths)
- [ ] Layer 1 — Sandboxing: network isolation (prevent exfiltration to attacker servers)
- [ ] Layer 1 — Sandboxing: process isolation (minimal privileges, not host user)
- [ ] Layer 1 — Client-side sandboxing: CVE-2025-6514 targeted client, run in containers/VMs
- [ ] Layer 2 — Authorization: OAuth scopes for tool-level permissions
- [ ] Layer 2 — Authorization: server-side access controls, do NOT rely on system prompt
- [ ] Layer 2 — Authorization: read-only database users, scoped API tokens
- [ ] Layer 2 — Authorization: MiniScope framework for formal permission hierarchies
- [ ] Layer 2 — Authorization layer, not LLM reasoning, is target for formal methods
- [ ] Layer 3 — Tool Integrity: pre-deployment scanning (static metadata analysis)
- [ ] Layer 3 — Tool Integrity: tool pinning (lock versions)
- [ ] Layer 3 — Tool Integrity: hash verification (detect tampering)
- [ ] Layer 3 — Tool Integrity: version verification (detect rug-pull)
- [ ] Layer 4 — Runtime Monitoring: behavioral anomaly detection
- [ ] Layer 4 — Runtime Monitoring: model decision path tracking
- [ ] Layer 4 — Runtime Monitoring: user transparency (show what tools are called and why)
- [ ] Layer 4 — Runtime Monitoring: explicit user confirmation for sensitive operations
- [ ] OWASP: isolate privileged tools in separate agent context
- [ ] OWASP: enforce restrictions server-side, not via system prompt
- [ ] OWASP: require explicit user confirmation for sensitive operations
- [ ] OWASP: validate/sanitize tool responses before adding to LLM context
- [ ] OWASP: separate privilege levels for internal vs external tools
- [ ] OWASP: do not let untrusted external server trigger calls to trusted internal tools
- [ ] Multi-layered defense: static metadata analysis + decision path tracking + anomaly detection + user transparency
- [ ] Read MCP developer guide for protocol
- [ ] Read MCP authentication for auth
- [ ] Read MCP transports for transport security
- [ ] Read build MCP server for server security
- [ ] Read Claude Desktop MCP for desktop security
- [ ] Test: tool poisoning attack — verify defense detects malicious metadata
- [ ] Test: cross-server exfiltration — verify context isolation prevents manipulation
- [ ] Test: rug-pull — verify tool pinning detects version changes
- [ ] Test: sandboxing — verify filesystem and network isolation
- [ ] Test: authorization — verify server-side controls cannot be bypassed by prompt injection
- [ ] Document threat model, attack vectors, defense layers, and incident response plan
FAQ
What are the main MCP security risks?
MCP introduces tool poisoning, prompt injection, cross-server data exfiltration, rug-pull attacks, confused deputy, and supply-chain attacks. Arxiv: "MCP introduces significant security vulnerabilities, particularly on the client side. Tool poisoning — where malicious instructions are embedded in tool metadata — is the most prevalent and impactful client-side vulnerability. STRIDE and DREAD threat modeling across five components: MCP Host+Client, LLM, MCP Server, External Data Stores, Authorization Server." OWASP: "MCP Tool Poisoning is an indirect prompt injection attack. Malicious MCP server tools look normal but responses contain hidden instructions. When AI agent calls tool, injected instructions land in LLM context window and get treated as trusted input." Survey: "Demonstrated incidents: GitHub MCP exploit (May 2025) — crafted issue caused agent to access private repos and exfiltrate data. WhatsApp MCP exploit (April 2025) — malicious server injected instructions to exfiltrate chat history. CVE-2025-6514 (CVSS 9.6) — OS command injection in mcpremote with 437,000+ downloads."
What is MCP tool poisoning and how does it work?
Tool poisoning embeds malicious instructions in tool metadata (descriptions, parameters, responses) that the LLM treats as trusted input. OWASP: "Attacker runs malicious MCP server. Tools look normal but responses contain hidden instructions. When AI agent calls tool, injected instructions land in LLM context window and get treated as trusted input. LLM follows them — calling restricted tools, leaking data, or bypassing system prompt. Root cause is trust gap between connect-time and runtime: tool descriptions reviewed once at connect, but tool responses go straight into LLM context with no equivalent check." Arxiv: "Tool poisoning is a specific form of indirect prompt injection in which malicious instructions are embedded in tool metadata rather than user inputs. This exploits the client-server trust model: clients receive tool definitions from servers and pass them to LLMs for decision-making." Attack flow: (1) Attacker runs malicious MCP server. (2) Tools appear normal at connect time. (3) Agent calls tool. (4) Response contains hidden instructions. (5) LLM follows injected instructions. (6) Agent calls restricted tools, reads sensitive files, or sends data to attacker.
What is cross-server data exfiltration in MCP?
Cross-server exfiltration exploits the shared LLM context window where multiple MCP servers' outputs mix, allowing a malicious server to manipulate calls to legitimate servers' tools. Survey: "Cross-server data exfiltration exploits the shared context window. In the WhatsApp MCP exploit (April 2025), a malicious random fact of the day server injected instructions that caused the agent to use a legitimate WhatsApp server send_message tool to exfiltrate the user entire chat history to an attacker-controlled phone number. The malicious server was never called directly — the attack operated purely through context contamination. Tool shadowing enables one malicious server to alter behavior of other servers tools. MCPLib attack library documented 31 distinct methods including Shadow Attacks, Malicious Tool Coverage, and Tool Preference Manipulation, all achieving success rates above 70%." Schneider: "Cross-server exfiltration exploits the fact that multiple servers share the model context within the second trust boundary."
How do you defend against MCP security risks?
Use defense-in-depth with four layers: sandboxing, authorization boundaries, tool integrity verification, and runtime monitoring. Schneider: "Securing MCP requires defense in depth across four layers: sandboxing, authorization boundaries, tool integrity verification, and runtime monitoring. The unifying principle: treat tool descriptions as code. Sandboxing provides filesystem isolation, network isolation, and process isolation. Client-side sandboxing matters too — CVE-2025-6514 demonstrated command injection targeting the MCP client itself." Arxiv: "Multi-layered defense strategy encompassing static metadata analysis, model decision path tracking, behavioral anomaly detection, and user transparency mechanisms." OWASP: "Isolate privileged tools. Enforce restrictions server-side. Require explicit user confirmation for sensitive operations. Do not rely on system prompt instructions to restrict tool access." Arxiv: "MCPSec protocol extension adds capability attestation and message authentication, reducing attack success rates from 52.8% to 12.4% with median latency overhead of 8.3ms."
What real-world MCP security incidents have occurred?
Multiple documented incidents include GitHub MCP exploit, WhatsApp exfiltration, Supabase/Cursor SQL injection, CVE-2025-6514, and Smithery platform breach. Survey: "GitHub MCP exploit (May 2025) — crafted GitHub issue caused agent to access private repositories and exfiltrate data through a public pull request. Supabase/Cursor exploit (June 2025) — support ticket containing malicious SQL was executed by agent with service-role database access. WhatsApp MCP exploit (April 2025) — malicious server injected instructions to exfiltrate entire chat history. Zero-click attacks through Jira and Google Docs MCP servers — malicious content auto-executed without user interaction. CVE-2025-6514 (CVSS 9.6) — OS command injection in mcpremote, most popular OAuth proxy for MCP with 437,000+ downloads, allowed remote code execution. Smithery hosting platform breach (October 2025) — path-traversal vulnerability exfiltrated Fly.io API token controlling over 3,000 applications. Rug-pull attacks — servers silently substitute malicious versions after one-time tool approval." Schneider: "MCP security is an architectural concern. It cannot be bolted on after deployment."
Want a self-hosted AI company brain that does all of this out of the box?
Book a demo →