{"affected":[{"database_specific":{"source":"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/09/GHSA-33f5-2c5q-wgwj/GHSA-33f5-2c5q-wgwj.json"},"package":{"ecosystem":"crates.io","name":"rmcp","purl":"pkg:cargo/rmcp"},"ranges":[{"events":[{"introduced":"0"},{"fixed":"2.0.0"}],"type":"SEMVER"}]}],"aliases":["CVE-2026-63127"],"database_specific":{"cwe_ids":["CWE-345"],"github_reviewed":true,"github_reviewed_at":"2026-09-16T22:13:26Z","nvd_published_at":"2026-09-16T15:17:39Z","severity":"HIGH"},"details":"### Summary\nThe `rmcp` library does not validate the `resource` parameter in OAuth Protected Resource metadata (RFC 9728), allowing a malicious MCP server to redirect OAuth flows to a legitimate authorization server and steal the resulting access tokens.\n\n### Details\nRFC 9728 specifies two MUST requirements for resource parameter validation:\n- Section 7.3: the client MUST ensure that the resource identifier URL it is using as the prefix for the metadata request exactly matches the `resource` value in the returned metadata document.\n- Section 3.3: if the `resource` value returned is not identical to the URL the client used, the data MUST NOT be used.\n\nIn the current implementation (`crates/rmcp/src/transport/auth.rs`), the `ResourceServerMetadata` struct (lines 390–394) does not include a resource field:\n```rust\nstruct ResourceServerMetadata {\n    authorization_server: Option<String>,\n    authorization_servers: Option<Vec<String>>,\n    scopes_supported: Option<Vec<String>>,\n}\n```\nAnd discover_oauth_server_via_resource_metadata() (lines 1446–1465) proceeds without any resource URL validation.\n\n#### Recommended fix\n1. Add the `resource` field to the struct:\n    ```rust\n    struct ResourceServerMetadata {\n        resource: Option<String>,  // RFC 9728 REQUIRED field\n        authorization_server: Option<String>,\n        authorization_servers: Option<Vec<String>>,\n        scopes_supported: Option<Vec<String>>,\n    }\n    ```\n2. Add validation logic after fetching metadata:\n    ```rust\n    let Some(resource_metadata) = self\n        .fetch_resource_metadata_from_url(&resource_metadata_url)\n        .await?\n    else {\n        return Ok(None);\n    };\n \n    // RFC 9728: validate that the resource identifier matches our target server\n    if let Some(resource) = &resource_metadata.resource {\n        if resource.trim_end_matches('/') != self.base_url.as_str().trim_end_matches('/') {\n            return Err(AuthError::MetadataError(format!(\n                \"Resource metadata mismatch: expected '{}', got '{}'\",\n                self.base_url, resource\n            )));\n        }\n    }\n    ```\n\n### PoC\n\n1. Attacker sets up a malicious MCP server at `fake-mcp.com/mcp`. \n2. At `fake-mcp.com/mcp/.well-known/oauth-protected-resource`, the attacker serves metadata declaring:\n    - resource: `real-mcp.com/mcp` (the legitimate server)\n    - authorization_servers: the legitimate authorization server(s) of `real-mcp.com/mcp`\n\n\n3. Victim configures any MCP client using `rmcp` to connect to `fake-mcp.com/mcp`.\n\n4. `rmcp` fetches the protected resource metadata and, without validating that the `resource` field (`real-mcp.com/mcp`) differs from the configured server (`fake-mcp.com/mcp`), initiates an OAuth flow with the legitimate authorization server.\n5. The victim sees a legitimate authorization prompt and completes the flow.\n6. The resulting access token — valid for `real-mcp.com/mcp` — is sent to `fake-mcp.com/mcp` in subsequent requests.\n7. The attacker captures the token and can impersonate the victim on `real-mcp.com/mcp`.\n\n### Impact\nThis is an access token theft vulnerability via OAuth resource metadata spoofing. All MCP clients built on `rmcp` that rely on OAuth-protected MCP servers are affected. An attacker who tricks a user into connecting to a malicious MCP server can steal valid access tokens for any legitimate MCP server, enabling full impersonation of the victim.\n\n#### Credit\nJian Cui, Minsun Shim, Zhou Li, Xiaojing Liao\nUniversity of Illinois Urbana-Champaign (UIUC)\nUniversity of California, Irvine (UCI)","id":"GHSA-33f5-2c5q-wgwj","modified":"2026-09-16T22:30:08.107391372Z","published":"2026-09-16T22:13:26Z","references":[{"type":"WEB","url":"https://github.com/modelcontextprotocol/rust-sdk/security/advisories/GHSA-33f5-2c5q-wgwj"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-63127"},{"type":"WEB","url":"https://github.com/modelcontextprotocol/rust-sdk/pull/937"},{"type":"WEB","url":"https://github.com/modelcontextprotocol/rust-sdk/commit/c1a8b29ff2cc45e7820b900dae42cbb4958089ec"},{"type":"PACKAGE","url":"https://github.com/modelcontextprotocol/rust-sdk"},{"type":"WEB","url":"https://github.com/modelcontextprotocol/rust-sdk/releases/tag/rmcp-v2.0.0"}],"schema_version":"1.9.0","severity":[{"score":"CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:L/A:N","type":"CVSS_V3"}],"summary":"RMCP: Missing Resource Field Validation in OAuth Protected Resource Metadata Discovery"}