For the complete documentation index, see llms.txt. This page is also available as Markdown.

MCP Bug Hunting

Model Context Protocol · Attack Surface · Methodology · Real CVEs · Tooling Setup


What is MCP?

MCP (Model Context Protocol) is a standard introduced by Anthropic in late 2024. It acts as a universal bridge between an LLM and external services — databases, APIs, filesystems, SaaS platforms. Think of it as the "plugin system" for AI models.

An MCP server exposes three primitive types:

  • Resources — read-only data (files, DB records, documents)

  • Tools — executable functions the LLM can invoke (API calls, shell commands, queries)

  • Prompts — predefined LLM interaction templates

Transport layer: MCP servers typically use SSE (Server-Sent Events), WebSockets, or STDIO. SSE is most common on publicly exposed servers. WebSockets often require auth. STDIO is used for local IDE integrations (Cursor, Claude Code, Copilot).


Attack Surface Overview

  • Publicly exposed MCP endpoints with no authentication

  • MCP tools that call internal APIs/DBs without authorization checks

  • Trust bypass in IDE MCP config files (Cursor, Claude Code, Copilot)

  • Prompt injection through malicious MCP tool descriptions

  • RCE via unsafe deserialization or Function()/eval() of user-supplied MCP config

  • Cross-tenant data access — tools leaking other tenants' data

  • IDOR in tool calls — changing IDs in MCP requests returns other users' data

  • Sensitive data in tool schemas and server info (API keys, internal URLs)


Recon & Discovery

Finding exposed MCP servers

Probe these endpoints during recon:

Look for response headers: Content-Type: text/event-stream and X-MCP-Server.

Shodan/Fofa dorks: http.header:"text/event-stream" mcp

Initial fingerprinting — raw SSE handshake

Response:

The initialize response reveals name, version, and available primitives. Tool names often hint at backend access (get_customer_record, run_sql_query, list_files).


Tooling Setup

Option A — MCP-ASD (Burp Extension)

Repo: https://github.com/hoodoer/MCP-ASD By: TrustedSec (Drew Kirkpatrick) Status: Submitted to BApp Store, pending approval as of early 2026 — install manually from GitHub.

The most capable MCP testing tool for Burp Suite. Builds an internal synchronous bridge that converts async SSE/WebSocket sessions into normal request-response pairs, so Repeater and Intruder work exactly as they would against a REST API.

Features:

  • Passive + active detection of MCP endpoints across all domains seen in Burp

  • Connects and enumerates all Tools, Resources, and Prompts

  • Auto-generates prototype requests for each primitive

  • Sends requests to Repeater or Intruder with one click

  • Handles auth: Bearer tokens, custom headers, mTLS certs, auth params

Setup steps:

  1. Download the .jar from GitHub releases

  2. In Burp: Extensions → Add → Java → select the jar

  3. Go to the MCP-ASD tab → Settings → enable active detection if needed

  4. Browse the target normally or enter the MCP URL directly

  5. MCP-ASD detects the server and adds an informational finding

  6. Click "Start New Connection" → auto-detect endpoints → connect

  7. Select any Tool/Resource/Prompt → prototype request appears → send to Repeater

Note: SSE connections stay open indefinitely. MCP-ASD abstracts this entirely so you don't deal with streaming responses manually.


Option B — mcp-client-and-proxy (for STDIO servers)

Repo: https://github.com/appsecco/mcp-client-and-proxy By: Appsecco

A Python-based MCP client that proxies STDIO transport over HTTP so Burp can intercept the traffic. Best for local MCP servers (IDE integrations) and servers that require OAuth.

Setup:

Create mcp_config.json in the project root:

Run:

The tool handles OAuth redirect, exposes a local HTTP interface, and all MCP calls flow through Burp as regular HTTP requests you can intercept and modify.


Option C — Manual proxy chain for HTTP-based MCP

For remote SSE servers where you want to intercept raw traffic without MCP-ASD:

Burp config:

  1. Install Burp's CA cert in your system trust store (Burp → Proxy → CA Certificate → export, then import to OS)

  2. Proxy → Options → enable "Support invisible proxying" for transparent interception

  3. For WebSockets: enable the WebSockets history tab in Burp — WS frames are natively captured

  4. For SSE: each MCP session appears as one long HTTP response — scroll the response pane to see streaming events

Tip: MCP-ASD eliminates all this friction. Use manual proxying only when you need raw access to the protocol or MCP-ASD doesn't support the transport variant.


Testing Methodology

Phase 1 — Enumerate everything

  • Map every tool to what backend it likely touches (SQL? filesystem? internal API?)

  • Read tool descriptions carefully — prompt injection often hides in descriptions

  • Check if initialize or server-info leaks internal service names, paths, or credentials


Phase 2 — Authorization testing

This is where most bug bounty wins come from. MCP servers often expose tools without applying the same permission checks as the main application.

  1. Create two accounts with different privilege levels (admin + low-priv)

  2. Invoke every tool from the low-priv account that should be admin-only

  3. Modify resource URIs: change resource://tenant-A/file.txtresource://tenant-B/file.txt

  4. In tool call parameters, swap IDs: "contact_id": "123" → another user's ID

  5. Try calling tools with no auth token at all

  6. Test horizontal privilege escalation: same role, different tenant/org

Real bug example (1day — Bugcrowd writeup):

A platform's MCP server exposed tools like list_conversations and get_contact. A low-priv account with no can_access_inbox or can_access_contacts permissions was able to invoke these tools directly via the MCP endpoint and retrieve all conversations and contact records across the tenant. Classic BOLA — the MCP tool layer had zero permission checks, while the web app layer did.

The researcher's approach: set a "flag" message (IF YOU READ THIS, IT WORKED!!) from the admin account, then attempt to retrieve it from the zero-priv MCP session. Confirmed the bypass immediately.


Phase 3 — Injection testing

For every string parameter in every tool call:

Use Burp Collaborator payloads for out-of-band detection — many injections won't return output directly but will trigger DNS or HTTP callbacks.

For MCP config fields (any "connect your own MCP server" feature):


Phase 4 — IDE/client trust model attacks

If the target involves IDE integrations (Cursor, Claude Code, VS Code extensions):

  • Look for MCP config files committed to shared Git repos: .cursor/, .vscode/, CLAUDE.md

  • Check whether modifying an approved MCP entry's command or args re-triggers an approval prompt

  • Look for mcp.json, claude_desktop_config.json, cursor_config.json in repo history (git log --all --full-history -- "**mcp*")

  • Inject prompt injection into tool descriptions: instructions that manipulate the LLM into exfiltrating data or executing unintended actions

  • Test tool poisoning: register a malicious MCP server alongside a legitimate one using the same tool name to shadow it


Phase 5 — Prompt injection through MCP

MCP tool descriptions are text that gets fed directly to the LLM. A malicious MCP server can hijack the AI's behavior through its own metadata:

When the LLM reads the tool list, it may follow embedded instructions. This is particularly dangerous in agentic workflows where the LLM acts autonomously over multiple steps.


Real CVEs — Annotated

CVE-2025-54136 — MCPoison: Cursor IDE trust bypass → persistent RCE

Severity: Critical Source: Check Point Research, Aug 2025 Affected: Cursor IDE Tags: RCE, Trust Bypass, Persistence

Cursor's one-time MCP approval model binds trust to the key name (e.g., "my-plugin"), not to the actual command or args. An attacker commits a benign .cursor/rules/mcp.json with an innocent command. Victim approves it once. Attacker then pushes an update replacing the command with a reverse shell. Every subsequent time the victim opens the project — the shell fires silently with no new prompt.

Where shell.bat contains a reverse shell payload back to the attacker.

Bug hunting angle: In shared repos, check if any approved MCP entries have recently changed command or args without re-triggering approval. Test if your own IDE prompts you again after you modify an existing approved entry. Report if it doesn't.


CVE-2025-59528 — Flowise CustomMCP node: RCE via Function() constructor

Severity: Critical Source: GitHub Advisory, Sep 2025 Affected: Flowise ≤ 3.0.5 (patched in 3.0.6) Tags: RCE, Code Injection

The CustomMCP node in Flowise lets users paste an MCP server config string. Internally, convertToValidJSONString passes that input directly into JavaScript's Function() constructor — functionally identical to eval(). Since Flowise runs Node.js with full privileges, this gives access to child_process, fs, and everything else.

Vulnerability flow:

  1. User input received via CustomMCP node UI

  2. Input passed to convertToValidJSONString()

  3. Function internally calls new Function(userInput)()

  4. Arbitrary JS executes with Node.js server privileges

Bug hunting angle: Any app feature that lets you "paste MCP server config" or "connect a custom MCP server" is a prime target. Look for eval, Function(), vm.runInContext in the source if you have access. Black-box: submit a payload that triggers a DNS pingback to Burp Collaborator.


CVE-2025-8943 — Flowise OS command injection via MCP tool parameters

Severity: Critical Source: JFrog Security Research, 2025 Affected: Flowise Tags: OS Command Injection, MCP Tool Abuse

A separate Flowise vulnerability where MCP tool call parameters are passed unsanitized to OS-level shell operations. User-supplied input in tool arguments flows into command execution without escaping. Classic command injection, accessed through the MCP tool interface.

Bug hunting angle: For every MCP tool that accepts string input, inject shell metacharacters. Even if the tool description says "search files" or "run a query", test ;ping your-collaborator.com in every parameter field. Out-of-band detection via Burp Collaborator is the most reliable method since output often isn't reflected.


CVE-2025-64755 — Claude Code: command execution via web-hosted MCP

Severity: High Source: SpecterOps / Adam Chester, Nov 2025 Affected: Claude Code Tags: RCE, AI Client

Found while demonstrating web-hosted MCP risks to a client. The research identified a command execution primitive within Claude Code's MCP integration. Web-hosted MCP servers can be crafted to gain code execution on the developer's machine through the IDE's MCP client. Same category as MCPoison but targeting Claude Code's trust model.

Bug hunting angle: If your target integrates with Claude Code, look at what MCP servers are auto-loaded via CLAUDE.md. Check whether MCP server tool descriptions can inject commands into Claude's reasoning loop.


Quick Checklist


Key Resources

  • MCP-ASD Burp extension — https://github.com/hoodoer/MCP-ASD

  • mcp-client-and-proxy — https://github.com/appsecco/mcp-client-and-proxy

  • MCP in Burp Suite (TrustedSec) — https://trustedsec.com/blog/mcp-in-burp-suite-from-enumeration-to-targeted-exploitation

  • MCPoison writeup (CVE-2025-54136) — https://research.checkpoint.com/2025/cursor-vulnerability-mcpoison/

  • An Evening with Claude Code (CVE-2025-64755) — https://specterops.io/blog/2025/11/21/an-evening-with-claude-code/

  • MCP IDOR bug bounty writeup — https://1-day.medium.com/how-i-discovered-a-rare-vulnerability-in-mcp-server-bug-bounty-28a0ef643902

  • Flowise OS RCE (JFrog) — https://research.jfrog.com/vulnerabilities/flowise-os-command-remote-code-execution-jfsa-2025-001380578/

  • HackTricks MCP Pentesting — https://hacktricks.wiki/en/AI/AI-MCP-Servers.html

Last updated