MCPmatic

MCP security best practices

Published · Updated · Written against MCP spec 2026-07-28

The MCP specification includes a security best practices page that names specific attacks against MCP servers and clients, and says what implementations MUST or SHOULD do about each. This is a plain-English summary for builders. For a release checklist, see the MCP server security checklist.

At a glance#

AttackWho's exposedThe fix in one line
Confused deputyMCP proxy servers using a shared OAuth clientGet the user's consent per client before forwarding
Token passthroughServers that forward client tokens downstreamOnly accept tokens issued for your server
SSRFClients and servers that fetch URLsBlock private ranges, require HTTPS, check redirects
State handle hijackingServers that keep state across callsRandom handles bound to the user, never used as auth
Local server compromiseUsers of one-click local installsShow the exact command; prefer stdio
Malicious auth URLsClients that open login URLsAllow only http/https; never open URLs through a shell
Mix-up attacksClients talking to several auth serversValidate the iss parameter (RFC 9207)
Over-broad scopesEveryone using OAuthRequest the least scope each operation needs

Confused deputy#

An MCP server acting as a proxy to a third-party API often uses one static OAuth client for all its users. If the third party remembers consent, an attacker can trick a user's browser into skipping the consent screen and send the authorization code to the attacker. The spec says such proxies MUST obtain the user's consent for each dynamically registered client before forwarding to the third-party authorization server.

Token passthrough#

"Token passthrough" means accepting a token from the client and forwarding it to a downstream API without checking it was meant for you. The spec explicitly forbids it: servers MUST NOT accept tokens that were not issued for the MCP server. Passthrough bypasses your rate limits and validation, breaks audit trails, and lets a stolen token reach further. Validate the token's audience, and use your own credentials for downstream calls.

Server-side request forgery (SSRF)#

Anything that fetches a URL supplied by someone else, such as OAuth metadata discovery or a "fetch this page" tool, can be pointed at internal addresses like cloud metadata endpoints. The guidance: require HTTPS outside development, block private and link-local IP ranges, validate redirect targets as well as the first URL, and consider an egress proxy.

State handle hijacking#

Without protocol sessions, servers that need state pass explicit handles (a cart id, a job id) between calls. The spec says servers MUST NOT treat a handle as authentication, and should use secure random, non-guessable handles bound to the authenticated user, so a leaked or guessed handle can't be used by someone else. Check authorization on every request.

Local MCP server compromise#

A local server runs with the user's permissions, and a malicious install command can do anything the user can. For one-click setups, clients MUST show the exact command that will run and get explicit approval, and should highlight dangerous patterns. Local servers SHOULD use stdio, or restrict HTTP access (for example with an auth token or a Unix socket) so other software on the machine can't reach them.

Malicious authorization URLs#

A malicious server can hand the client a "login" URL that's really a command or a local file. Clients should accept only http: and https: URLs and MUST NOT open them by passing them to a shell. Use the platform's safe URL-opening API, and test your client with a hostile URL before you ship.

Mix-up attacks#

A client that talks to several authorization servers can be tricked into sending a code from one to another. Validate the iss parameter in authorization responses, as described in RFC 9207.

Scope minimisation#

Requesting every scope up front means a leaked token can do everything. Start with minimal scopes and request more when an operation needs them.

Tool-level basics#

The tools section of the spec adds four MUSTs for every server: validate all tool inputs, implement access controls, rate limit tool invocations, and sanitize tool outputs. Clients SHOULD ask the user to confirm sensitive operations and show tool inputs before calling. Tool annotations help with that, but are untrusted hints, not controls (see annotations).

The linter flags tool parameters that look like credentials, and x-mcp-header on sensitive-looking parameters.

Frequently asked questions#

Can an MCP server pass the user's token to my API?

No. The spec says servers MUST NOT accept tokens that weren't issued for the MCP server, which rules out forwarding a client token downstream. Use separate credentials for downstream calls.

Are tool annotations a security control?

No. They're hints. Clients must treat them as untrusted unless the server is trusted, and servers still need access controls.

Sources#