| OAuth 2.1 at the authorization serverbasic/authorization | “Authorization servers MUST implement OAuth 2.1 with appropriate security measures for both confidential and public clients.” | It does not protect a stdio server. Authorization is OPTIONAL in MCP overall, and the specification itself says: “Implementations using an STDIO transport SHOULD NOT follow this specification, and instead retrieve credentials from the environment.” A locally-run server is protected by whoever runs it and by that user's machine permissions — not by OAuth. |
|---|
| PKCE, S256, and refuse-to-proceedbasic/authorization | “MCP clients MUST implement PKCE according to OAuth 2.1 Section 7.5.2 and MUST verify PKCE support before proceeding with authorization.”“MCP clients MUST use the S256 code challenge method when technically capable, as required by OAuth 2.1 Section 4.1.1.”“If code_challenge_methods_supported is absent, the authorization server does not support PKCE and MCP clients MUST refuse to proceed.” | The obligation to verify support and to refuse to proceed is new in the 2025-11-25 revision. The 2025-06-18 revision required PKCE but carried neither the verify nor the refuse-to-proceed language. That is exactly the question to put to any vendor claiming “MCP auth support”: against which revision, and what does your client do when the field is absent. |
|---|
| RFC 9728 Protected Resource Metadatabasic/authorization | “MCP servers MUST implement OAuth 2.0 Protected Resource Metadata (RFC9728). MCP clients MUST use OAuth 2.0 Protected Resource Metadata for authorization server discovery.”“The Protected Resource Metadata document returned by the MCP server MUST include the authorization_servers field containing at least one authorization server.” | Discovery metadata is attacker-influenceable. The fields that come out of it feed outbound requests from the gateway — which is why it flows straight into the SSRF row at the bottom of this table and is never treated as trusted input. |
|---|
| RFC 8707 resource indicatorsbasic/authorization | “MCP clients MUST implement Resource Indicators for OAuth 2.0 as defined in RFC 8707 to explicitly specify the target resource for which the token is being requested.”“The resource parameter: 1. MUST be included in both authorization requests and token requests.”“MCP clients MUST send this parameter regardless of whether authorization servers support it.” | Sending the parameter does not bind the token. If the authorization server does not honour it, the token you get back is still over-broad. The real enforcement point is the audience check in the next row, on our side. |
|---|
| Audience validation on every inbound tokenbasic/authorization | “MCP servers MUST validate that access tokens were issued specifically for them as the intended audience, according to RFC 8707 Section 2.”“MCP servers MUST only accept tokens that are valid for use with their own resources.”“MCP servers MUST NOT accept or transit any other tokens.” | The quote is from the 2025-11-25 revision. In 2025-06-18 the middle sentence read “Authorization servers MUST only accept…” — placing the obligation on a different party. If you are reading an older document, you are reading an obligation that is not yours. |
|---|
| No token passthrough, everbasic/authorizationbasic/security_best_practices | “The MCP server MUST NOT pass through the token it received from the MCP client.”“MCP servers MUST NOT accept any tokens that were not explicitly issued for the MCP server.” | The specification names the documented consequences of breaking this rule: circumvention of “rate limiting, request validation, or traffic monitoring”, broken audit trails, and “a malicious actor in possession of a stolen token can use the server as a proxy for data exfiltration”. The rule does not protect against a legitimately issued token being misused — that is what the approval gate and the audit log are for. |
|---|
| Authorization server discoverybasic/authorization | “MCP authorization servers MUST provide at least one of the following discovery mechanisms: OAuth 2.0 Authorization Server Metadata (RFC8414) [—] OpenID Connect Discovery 1.0”“MCP clients MUST support both discovery mechanisms to obtain the information required to interact with the authorization server.” | A genuine cross-revision change: 2025-06-18 required RFC 8414 only, with no OIDC option. A client built against the older document may not know how to read OIDC Discovery metadata at all. |
|---|
| Session handlingbasic/security_best_practices | “MCP servers that implement authorization MUST verify all inbound requests. MCP Servers MUST NOT use sessions for authentication.”“MCP servers MUST use secure, non-deterministic session IDs. Generated session IDs (e.g., UUIDs) SHOULD use secure random number generators.” | A non-deterministic ID is a MUST, but secure-random generation of it is only a SHOULD — an implementation can meet the letter of the rule and still emit weak IDs. The specification recommends binding the ID to user identity in the form <user_id>:<session_id>. Beyond that, the whole mechanism is removed from the Streamable HTTP transport in the 2026-07-28 revision, so an architecture leaning on it is built on something already marked for exit. |
|---|
| Scope minimizationbasic/security_best_practices | “Minimal initial scope set (e.g., mcp:tools-basic) containing only low-risk discovery/read operations”“Publishing all possible scopes in scopes_supported”“Using wildcard or omnibus scopes (*, all, full-access)” | Scope minimization does not protect a field that is inside the granted scope. Runtime elevation happens through a challenge: the server returns 403 with error=“insufficient_scope”, the required scope and resource_metadata, and on a 401 it includes scope per RFC 6750 §3. If your client cannot handle the challenge, elevation fails silently. |
|---|
| Authorization URL validationbasic/security_best_practices | “MUST reject javascript:, data:, file:, vbscript:, and other potentially dangerous schemes”“The http:// scheme is acceptable only for loopback addresses (such as localhost, 127.0.0.1, or ::1) during local development; authorization servers in production MUST use https://.”“MCP clients MUST avoid shell execution when opening URLs: MUST NOT use shell commands (e.g., cmd.exe, sh, PowerShell) to open URLs” | These obligations sit on the client, not on our gateway — which means they are not ours to guarantee. We cannot fix an AI client that opens a URL through a shell command. The specification documents both outcomes of skipping the checks: JavaScript URL injection yielding an XSS context inside the client, and command injection yielding code execution with the user's privileges. What is ours: our gateway never returns an authorization URL originating from a third-party server to a client without validating its scheme. |
|---|
| SSRF defence on the gatewaybasic/security_best_practices | “During OAuth metadata discovery, MCP clients fetch URLs from several sources that could be controlled by a malicious MCP server.”“MCP clients deployed to a server MUST consider SSRF risks and implement appropriate mitigations when fetching OAuth-related URLs.”“For server-side MCP client deployments, operators SHOULD consider using an egress proxy that enforces network policies.” | The guidance to block private ranges (10/8, 172.16/12, 192.168/16), loopback (127/8, ::1), link-local 169.254/16 and private IPv6 (fc00::/7, fe80::/10) is SHOULD, not MUST — so it is guaranteed in no implementation you have not checked yourself. The specification explicitly names the cloud metadata service at 169.254.169.254, DNS rebinding and redirect chains, and points to Smokescreen as an egress proxy. |
|---|