CVE-2026-63127: RMCP: Missing Resource Field Validation in OAuth Protected Resource Metadata Discovery
The Rust MCP SDK `rmcp` before 2.0.0 does not check the `resource` field in OAuth Protected Resource metadata. A malicious MCP server can claim to be a legitimate one, steer the user through a real OAuth login, and then receive the resulting access token. Upgrade to rmcp 2.0.0.
Published Sep 16, 2026 · Analysis Oct 23, 2026
What an attacker can do
RFC 9728 says a client must confirm that the resource value in the metadata equals the server URL it used, and must discard the metadata if not. In crates/rmcp/src/transport/auth.rs, the ResourceServerMetadata struct has no resource field, and discover_oauth_server_via_resource_metadata() uses whatever it fetches.
The attack in the advisory: the attacker runs fake-mcp.com/mcp and serves metadata at /.well-known/oauth-protected-resource that names real-mcp.com/mcp as the resource and lists the real server's authorization servers. A victim points an rmcp-based client at the fake server. The client starts OAuth with the real authorization server, and the victim sees a genuine consent prompt and approves. The token, valid for the real server, is then sent to the fake server on later requests. The attacker can replay it to impersonate the victim.
The attacker needs the victim to connect to a server they control, which is user interaction in the CVSS vector. Any agent or tool built on rmcp that uses OAuth-protected MCP servers is affected. The consent screen is real, so users have no visible warning.
Who is affected
Affected: the Rust crate rmcp before 2.0.0, for clients that use its OAuth transport (transport/auth.rs) with OAuth-protected MCP servers. Check which version your project resolves:
cargo tree -i rmcpCheck Cargo.lock for the locked rmcp version too.
rmcp
- Ecosystem
- Rust (crates.io)
- Affected
- < 2.0.0
- Fixed in
- 2.0.0
- Check
cargo tree -i rmcp
How to fix it
Upgrade to rmcp 2.0.0.
cargo update -p rmcpIf the lockfile stays below 2.0.0, raise the version requirement in Cargo.toml to 2.0.0. The advisory's recommended fix adds the resource field to the metadata struct and returns an error when it does not match the configured base URL. The sources name no workaround. Until you upgrade, only connect to MCP servers you trust, and revoke tokens issued during sessions with unknown servers.
How to tell if you were hit
Review which MCP server URLs your rmcp clients were configured with, looking for hosts you do not own whose OAuth metadata names a different resource. Fetch /.well-known/oauth-protected-resource from each and compare its resource value with the server URL. At the authorization server, look for token grants followed by use of the token from unexpected IP addresses. After upgrading, a mismatch produces a MetadataError reading "Resource metadata mismatch" if the fix follows the advisory's suggestion.
Original advisory
From the GitHub Advisory Database (CC BY 4.0).
Summary
The 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.
Details
RFC 9728 specifies two MUST requirements for resource parameter validation:
- 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
resourcevalue in the returned metadata document. - Section 3.3: if the
resourcevalue returned is not identical to the URL the client used, the data MUST NOT be used.
In the current implementation (crates/rmcp/src/transport/auth.rs), the ResourceServerMetadata struct (lines 390–394) does not include a resource field:
struct ResourceServerMetadata {
authorization_server: Option<String>,
authorization_servers: Option<Vec<String>>,
scopes_supported: Option<Vec<String>>,
}And discover_oauth_server_via_resource_metadata() (lines 1446–1465) proceeds without any resource URL validation.
Recommended fix
- Add the
resourcefield to the struct: ``rust struct ResourceServerMetadata { resource: Option<String>, // RFC 9728 REQUIRED field authorization_server: Option<String>, authorization_servers: Option<Vec<String>>, scopes_supported: Option<Vec<String>>, }`` - Add validation logic after fetching metadata: ```rust let Some(resource_metadata) = self .fetch_resource_metadata_from_url(&resource_metadata_url) .await? else { return Ok(None); };
// RFC 9728: validate that the resource identifier matches our target server if let Some(resource) = &resource_metadata.resource { if resource.trim_end_matches('/') != self.base_url.as_str().trim_end_matches('/') { return Err(AuthError::MetadataError(format!( "Resource metadata mismatch: expected '{}', got '{}'", self.base_url, resource ))); } }
### PoC
1. Attacker sets up a malicious MCP server at `fake-mcp.com/mcp`.
2. At `fake-mcp.com/mcp/.well-known/oauth-protected-resource`, the attacker serves metadata declaring:
- resource: `real-mcp.com/mcp` (the legitimate server)
- authorization_servers: the legitimate authorization server(s) of `real-mcp.com/mcp`
3. Victim configures any MCP client using `rmcp` to connect to `fake-mcp.com/mcp`.
4. `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.
5. The victim sees a legitimate authorization prompt and completes the flow.
6. The resulting access token — valid for `real-mcp.com/mcp` — is sent to `fake-mcp.com/mcp` in subsequent requests.
7. The attacker captures the token and can impersonate the victim on `real-mcp.com/mcp`.
### Impact
This 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.
#### Credit
Jian Cui, Minsun Shim, Zhou Li, Xiaojing Liao
University of Illinois Urbana-Champaign (UIUC)
University of California, Irvine (UCI)Questions
- Is rmcp 1.x affected by CVE-2026-63127?
Yes, the advisory lists every version before 2.0.0 as vulnerable. The fixed release is 2.0.0.
- Would the user notice anything wrong?
No. The OAuth consent page comes from the real authorization server, so it looks legitimate. The theft happens when the client later sends the token to the attacker's server.
- Is it exploited in the wild?
No source reports exploitation and it is not in CISA's KEV catalog. The advisory credits researchers from UIUC and UC Irvine.
References
How this page is made: the data panel comes from the GitHub Advisory Database, CISA’s KEV catalog, the NVD and FIRST EPSS, and updates twice a day. The analysis is written by an AI model from the sources listed above and checked by automated rules before it is published. Check versions against the vendor's advisory before you act. Methodology
More MCP Rust SDK (rmcp) vulnerabilities
All MCP Rust SDK (rmcp) entriesGHSA-c9xm-49cp-xcr9
rmcp OAuth client fetches server-controlled resource_metadata URLs
medium6.3Oct 2, 2026CVE-2026-64684
RMCP: Custom HTTP headers leak to cross-origin redirect targets
medium6.8Sep 17, 2026CVE-2026-63128
RMCP: Unauthenticated permanent session-table leak in rmcp Streamable HTTP server transport leads to remote denial-of-service
high7.5Sep 16, 2026CVE-2026-42559
rmcp Streamable HTTP server transport has a DNS rebinding vulnerability
high8.8May 6, 2026
