MCPwell

Home › Security › Checklist

MCP Security Checklist: 12 Things to Check

Twelve checks, in the order of the MCP security best practices for protocol revision 2025-06-18. Each item names the section it comes from. Nothing here is a result from the MCPwell tester. The tester does not grade these controls. Token audience and scope rules that sit next to items 5, 6, and the scope discussion are written up on least-privilege tokens. The session-hijack prompt injection case is on prompt injection.

1. Per-client consent on a proxy

Section in the security best practices: Confused deputy.

If an MCP server is a proxy that uses one static OAuth client id with a third-party authorization server, and MCP clients can register dynamically, the security best practices say the proxy must keep its own consent record per client and per user. It must check that record before it sends the user to the third-party authorization server. A consent cookie left by an earlier approval of the static client id is the gap the attack uses.

2. Say who is asking, and do not allow framing

Section in the security best practices: Consent UI requirements.

The MCP-level consent page must name the requesting MCP client, show the third-party scopes being requested, and show the registered redirect URI. It must use CSRF protection. It must stop framing, with a frame-ancestors content security policy or X-Frame-Options: DENY. That text is the specification's requirement for the consent page, not a description of any product in this directory.

3. Match redirect URIs exactly

Section in the security best practices: Redirect URI validation.

The proxy must check that the redirect URI on the authorization request is an exact string match for the URI registered for that client. The security best practices say to reject the request if the redirect URI changed without a new registration, and not to use pattern matching or wildcards.

4. Save the OAuth state only after consent

Section in the security best practices: OAuth state parameter.

The specification says the proxy must create a cryptographically secure random state value for each authorization request, store it only after the user approves the consent screen, and store it immediately before the redirect to the third-party identity provider. The callback must reject a missing or mismatched state. The value is single-use. The document gives 10 minutes as an example expiration, not as a number this site measured.

5. Reject tokens that were not issued for this server

Section in the security best practices: Token passthrough.

The security best practices say an MCP server must not accept any token that was not explicitly issued for the MCP server. The authorization specification says the same thing as an audience check: the server validates that the token was issued for itself, and it rejects other tokens. A failed check is HTTP 401.

6. Do not forward the client's token downstream

Section in the security best practices: Token passthrough.

Token passthrough, in that document, is an MCP server accepting a token and sending that same token on to a downstream API. The mitigation line is the same rule as the previous item: do not accept a token that was not issued for the MCP server. The authorization specification adds that a call to an upstream API uses a separate token issued by the upstream authorization server.

7. Use HTTPS for OAuth URLs

Section in the security best practices: Server-side request forgery.

For OAuth metadata URLs, the security best practices say production clients should require HTTPS. The exception they name is a loopback address during development: localhost, 127.0.0.1, or ::1. The authorization specification requires authorization-server endpoints to be served over HTTPS, and requires redirect URIs to be localhost or HTTPS.

8. Block private and link-local addresses

Section in the security best practices: Server-side request forgery.

When a client fetches OAuth URLs that a server supplied, the security best practices say it should block private IPv4 ranges 10.0.0.0/8, 172.16.0.0/12, and 192.168.0.0/16, loopback 127.0.0.0/8 and ::1 except where development explicitly allows them, link-local 169.254.0.0/16 including the cloud metadata address, and private IPv6 fc00::/7 and fe80::/10. The same document says not to hand-roll IP parsing, and to apply the same checks to redirect targets.

9. Do not use the session id as a login

Section in the security best practices: Session hijacking.

MCP servers that implement authorization must verify every inbound request. The security best practices say servers must not use sessions for authentication. A session id that arrives on initialize is not a substitute for checking the credential on later requests.

10. Use a random session id, bound to the user

Section in the security best practices: Session hijacking.

Servers must use secure, non-deterministic session ids. The document says generated ids such as UUIDs should come from a secure random number generator, and that predictable or sequential ids are a guessing risk. It also says servers should bind the session id to user-specific information, for example a key of user id plus session id, so a guessed session id is not enough to impersonate someone else.

11. Show the exact local command before it runs

Section in the security best practices: Local MCP server compromise.

If a client can add a local MCP server in one step, the security best practices say it must show a consent dialog first. The dialog must show the exact command, including arguments, without truncation, say that the command runs on the user's system, and require an explicit approval. The document's examples of malicious startup commands are a reason for that dialog. This page does not repeat those commands.

12. Allow only http and https authorization URLs

Section in the security best practices: OAuth authorization URL validation.

Clients must validate authorization URLs from a server. The specification says to allow only http and https, with http only for loopback during development, and to reject javascript, data, file, vbscript, and other dangerous schemes. It also says not to open those URLs through a shell such as cmd.exe, sh, or PowerShell.

Scope minimization is the last section of that same document. It is not one of the twelve items above, because the tokens page cites it in full. Start with a small scope, and do not publish a wildcard scope as if it were required. The common mistakes the specification lists are on the tokens page.

A fact sheet that says Verified on MCPwell has passed initialize and tools/list only. That is not a check mark on this list. See what the badge means.

FAQ

Are these 12 checks a score for servers on MCPwell?

No. They are the controls the 2025-06-18 security best practices tell implementers to build. This directory does not mark a server pass or fail on them.

Does a Verified badge mean the checklist passed?

No. Verified means initialize and tools/list returned a result for that public URL on the date printed on the badge.

Which document is the source?

Security Best Practices, protocol revision 2025-06-18: https://modelcontextprotocol.io/specification/2025-06-18/basic/security_best_practices.