NewApp Monitoring is liveSign up free
AgentbeamBeta
AI agent vulnerability · MCP Rust SDK (rmcp)

CVE-2026-63127: RMCP: Missing Resource Field Validation in OAuth Protected Resource Metadata Discovery

highCVSS 3.1 8.2GHSA-33f5-2c5q-wgwj

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 rmcp

Check 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 rmcp

If 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 resource value in the returned metadata document.
  • Section 3.3: if the resource value 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

  1. Add the resource field 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>>, } ``
  2. 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) entries