MCP server security testing

An MCP server hands an AI model tools it can call, so its security comes down to three questions: who may call it, what each tool may do for that caller, and what untrusted text flows back into the model. Ghost Protocol tests MCP servers by hand as part of a penetration test of the application and API behind them, against the MCP specification’s security requirements and the OWASP lists for LLM and agentic applications.

Last reviewed

What we test on an MCP server

An MCP server is an API whose caller is a model acting for a person. Every check an API needs still applies, and a few more do, because the caller can be talked into things.

  • Authorisation on every request

    We replay one user's tool calls with a second user's identity, and with none, and record what the server does. A server that checks who you are once and trusts the session afterwards fails here.

  • Tenancy

    One customer's resources, prompts and tool results must never reach another customer. We look for shared caches, shared indexes, and state handles or session identifiers that are not tied to the user who holds them.

  • Token audience and token passthrough

    Whether the server accepts a token issued for some other service, and whether it forwards the token it received to the APIs behind it instead of using its own.

  • Tool permissions

    Whether each tool checks the caller's role itself, rather than trusting that the model chose well. A tool that deletes, pays or sends must refuse a caller who may not do that, whatever the prompt said.

  • Origin and transport

    Whether an HTTP server refuses browser requests from origins it does not know, which is the defence against DNS rebinding, and whether a local server is reachable by anything other than its own client.

  • Input size, rate limits and cost

    Whether the server caps what it reads and how often one caller may use an expensive tool, across a whole session rather than one request at a time.

  • Every URL the server fetches

    A tool that fetches a URL it was given can be pointed at internal addresses and cloud metadata. We test each one for server-side request forgery (API7:2023).

  • What flows back to the model

    Tool output, resources and tool descriptions are read by the model as text, so an instruction planted in any of them is an indirect prompt injection. We check what reaches the model, and from whom.

What the MCP specification requires, and what we check

Quoted from revision 2026-07-28 of the specification, the current one when we read it on 24 October 2026. That revision removed protocol-level sessions, so the session rule comes from revision 2025-11-25, which servers on older protocol versions still follow. MUST and SHOULD are the specification’s own words.

MCP specification security requirements, where each is written, and what we check
Where in the specificationWhat it requiresWhat we check
Streamable HTTP: Security & EndpointServers MUST validate the Origin header on all incoming connections to prevent DNS rebinding attacks. If the Origin header is present and invalid, servers MUST respond with HTTP 403 Forbidden.Requests from foreign origins, and what the server answers.
Authorization: Token HandlingMCP servers MUST validate that access tokens were issued specifically for them as the intended audience.Tokens issued for another service, expired tokens, tokens without the server in their audience.
Authorization: Token HandlingMCP servers MUST only accept tokens that are valid for use with their own resources. MCP servers MUST NOT accept or transit any other tokens.Whether the client's token is passed through to the APIs behind the server (token passthrough).
Security Best Practices: State Handle HijackingMCP servers that implement authorization MUST verify all inbound requests. MCP servers MUST NOT treat possession of a state handle as authentication.Calls replayed with another user's state handle, such as a cart or workflow ID, and how guessable the handles are.
Revision 2025-11-25, Security Best Practices: Session HijackingMCP servers that implement authorization MUST verify all inbound requests. MCP Servers MUST NOT use sessions for authentication.For servers on protocol versions that still use sessions: calls replayed with another user's session identifier.
Security Best Practices: Confused Deputy ProblemMCP proxy servers MUST implement per-client consent and proper security controls.For a server that fronts a third-party API with one client ID: consent per client, exact redirect URI matching, the OAuth state value.
Security Best Practices: Scope MinimizationImplement a progressive, least-privilege scope model.Wildcard or catch-all scopes, and tools that run without the scope they should need.
Streamable HTTP: Security & EndpointWhen running locally, servers SHOULD bind only to localhost (127.0.0.1) rather than all network interfaces (0.0.0.0).Where you ship a local server: what else on the machine or the network can reach it.

Where the findings sit in the OWASP lists

Each finding names its entry, so it lands in your compliance crosswalk without translation. The full LLM and agentic lists, entry by entry, are on the AI agent security testing page.

LLM01:2025 Prompt Injection
Instructions planted in tool output, resources or tool descriptions.
LLM06:2025 Excessive Agency
Tools that do more than the caller may, or more than the task needs.
LLM10:2025 Unbounded Consumption
No ceiling on how often one caller may run an expensive tool.
ASI02: Tool Misuse and Exploitation
Legitimate tools called with harmful arguments, or in a harmful order.
ASI03: Identity and Privilege Abuse
Tokens accepted from, or passed to, the wrong party; sessions trusted as identity.
API1:2023 Broken Object Level Authorization
One user's resources returned to another through a tool call.
API5:2023 Broken Function Level Authorization
An administrative tool callable by an ordinary user.
API7:2023 Server Side Request Forgery
A tool that fetches whatever URL it is given.

How we build our own MCP endpoint

This site runs a public MCP endpoint at ghosts.lk/mcp, on protocol version 2025-06-18 (an earlier revision than the one quoted above), and we publish Wyrm, a local MCP server. What they do, as their code describes it.

  • One list of tools for every surface

    The endpoint adds no capability of its own. It is a second door onto the same four tools the site’s assistant uses, rendered from one list, so a tool that is unsafe to expose is removed once and disappears from every surface together.

  • An allow-listed Origin, never echoed

    A browser request from an origin that is not ours is refused, and the caller’s Origin is never reflected back. Echoing it would let any page a visitor opens drive our tools from that visitor’s browser. MCP clients that are not browsers send no Origin, so they lose nothing.

  • A budget per session, not per request

    A session can call a tool again and again, so the scan and contact tools are capped per IP address in a store every server instance shares, with IPv6 addresses counted by their /64 network.

  • A cap on what it reads

    The endpoint reads at most 100,000 bytes of a request body, counted on the bytes actually read, never on the Content-Length header, which a caller can forge or leave out.

  • Nothing hostile handed back, and no false success

    The scan tool returns a grade, a score and the top fixes, never the scanned page’s content, so a hostile page cannot pass instructions to the model through the result. A contact request that fails to save is reported to the model as an error, so the model is not told it worked and has no reason to tell the person their details were sent.

  • Public by design, so no login

    Every tool on the endpoint is public: scan a public website, find a page on this site, offer a call, or pass on a contact request, which the endpoint’s instructions tell the model to send only after the person has agreed. It reads no private data, which is why it carries no login. A server that can reach anyone’s private data needs authorisation on every request.

  • Wyrm keeps untrusted memory out of the brief

    Wyrm runs on your own machine, started by the MCP client as a local command, with its memory in one SQLite file there. Every memory carries the lane it came from, and content from an untrusted source is withheld from the briefs an agent reads. Its 8.0.1 red-team used 622 jailbreak payloads from the garak corpus: 0 escaped the untrusted lane, by construction, and the detector flagged 80.7% of the rest with 0 false positives on ordinary prose. About Wyrm

What this test does not cover

  • Source-code audits of third-party MCP servers you install but do not run or control
  • The MCP client applications themselves, such as an editor or a desktop assistant
  • The model behind the client: jailbreak research, its guardrails, its training data
  • Mobile apps, internal corporate networks and physical security

Social engineering and red-team engagements are offered as separate engagements, scoped and quoted individually. The fixed-price web and API penetration test does not include them.

Scope and price

An MCP server is tested as the API in our fixed-price web and API penetration test, with the application it belongs to: up to three hostnames and two user roles, the report in 5 to 7 days, a signed attestation letter and a free re-test. Several servers, or more roles, are a larger scope, quoted in writing before anything starts. The method and the report are the same as for every test we run.

See how we test and what the report looks like, or the fixed-price penetration test itself.

Questions about MCP server security

Is MCP secure?

The protocol is a way to connect tools to a model. How safe a server is depends on how it is built: who may call it, what each tool may do for that caller, and what flows back to the model. The specification sets security requirements, such as Origin validation, token audience checks, no token passthrough, and never treating a session or a state handle as proof of who is calling. A server that ignores them is not made safe by the protocol.

Does an MCP server need authentication?

The specification makes authorization optional. Where it is supported, servers on an HTTP transport should follow the specification's OAuth-based rules, and servers on stdio should take credentials from the environment instead. In practice, any server that can reach private data or act for a user needs authorisation checked on every request.

What is token passthrough?

It is when an MCP server takes the token a client sent it and forwards that same token to another API, instead of checking that the token was issued for the server and using its own credentials upstream. The specification forbids it, because it bypasses the downstream API's checks and hides who is really calling.

Can prompt injection arrive through an MCP server?

Yes. Tool output, resources and tool descriptions all reach the model as text. A server that returns content it fetched from the web, an inbox or a shared document can carry an instruction someone planted there. We test what reaches the model and whether the server marks untrusted content as such.

How do you test an MCP server?

As the API in a penetration test of the application it belongs to: grey box, with two identities, every tool call replayed across them, tokens and sessions swapped, and planted content placed only in the test accounts you give us. Each finding is reproduced by hand, with the request and the response, before it reaches the report.

How much does MCP server security testing cost?

An MCP server and the application behind it are tested within our fixed-price web and API penetration test, $4,000, when they fit its scope of up to three hostnames and two user roles. Several servers, or more roles, are a larger scope and are quoted before we start. All prices are on the pricing page.

Tell us what your MCP server can reach

Email ryan@ghosts.lk or message +94 71 055 5055 on WhatsApp. Ryan replies within 24 hours. Working hours are Monday to Friday, 09:00 to 18:00 Colombo time (UTC+5:30).