Skip to main content
Vulnerability Database/CVE-2026-63128

CVE-2026-63128: RMCP Rust SDK DoS Vulnerability

CVE-2026-63128 is a denial of service flaw in RMCP Rust SDK that lets attackers exhaust server memory through repeated unauthenticated requests. This post covers technical details, affected versions, impact, and mitigation.

Published:

CVE-2026-63128 Overview

CVE-2026-63128 affects the rmcp crate, the official Rust SDK for the Model Context Protocol (MCP). The stateful Streamable HTTP server in crates/rmcp/src/transport/streamable_http_server/tower.rs creates a session before validating the incoming JSON-RPC message. Unauthenticated clients can send a well-formed non-initialization POST, or an initialization request with a mismatched MCP-Protocol-Version header, to insert orphaned session state that is never released. Repeated requests grow the shared session table without bound, causing lock contention, memory exhaustion, and eventual server termination. The issue is fixed in rmcp version 2.0.0 and tracked as [CWE-400] Uncontrolled Resource Consumption.

Critical Impact

An unauthenticated remote attacker can exhaust memory and terminate any rmcp Streamable HTTP server through repeated malformed JSON-RPC POST requests.

Affected Products

  • rmcp crate (Rust SDK for Model Context Protocol) prior to 2.0.0
  • Applications using StreamableHttpService with LocalSessionManager
  • MCP servers built on the stateful Streamable HTTP transport

Discovery Timeline

  • 2026-09-16 - CVE-2026-63128 published to the National Vulnerability Database
  • 2026-09-16 - Last updated in NVD database

Technical Details for CVE-2026-63128

Vulnerability Analysis

The defect lives in StreamableHttpService::handle_post. When a request arrives without an existing session identifier, the handler calls LocalSessionManager.create_session() before inspecting the JSON-RPC payload. The newly created LocalSessionHandle is inserted into the LocalSessionManager.sessions map immediately.

If subsequent validation determines the message is not an InitializeRequest, or that the MCP-Protocol-Version header does not match the initialization body, the handler returns an error. The error path does not remove the entry that was just inserted. The session and its associated channel state persist for the lifetime of the server process.

Each invalid request adds another orphaned session. The map grows without bound, the shared lock protecting the session table experiences increasing contention, and legitimate client requests slow down. Memory pressure eventually terminates the process.

Root Cause

The root cause is an ordering flaw: state allocation occurs before input validation. The handler treats session creation as unconditional setup rather than as a side effect that must be reverted on validation failure. There is no cleanup path in the early-return branches of handle_post.

Attack Vector

Exploitation requires only network access to the Streamable HTTP endpoint. No authentication, credentials, or user interaction are needed. An attacker sends repeated JSON-RPC POST requests that either omit the initialize method or supply a mismatched protocol version header. Each request leaks one session entry.

rust
                    }
                }
            } else {
-                let (session_id, transport) = self
-                    .session_manager
-                    .create_session()
-                    .await
-                    .map_err(internal_error_response("create session"))?;
                // Capture init params for external store persistence before
                // extensions are injected (which would require Clone).
-                let stored_init_params = if self.config.session_store.is_some() {
-                    if let ClientJsonRpcMessage::Request(req) = &message {
-                        if let ClientRequest::InitializeRequest(init_req) = &req.request {
-                            Some(init_req.params.clone())
-                        } else {
-                            None
-                        }
-                    } else {
-                        None
+                let stored_init_params = match &mut message {
+                    ClientJsonRpcMessage::Request(req) => {
+                        let ClientRequest::InitializeRequest(init_req) = &req.request else {
+                            return Err(unexpected_message_response("initialize request"));
+                        };
+                        // Reject mismatched MCP-Protocol-Version header before binding the session to anything.
+                        validate_header_matches_init_body(
+                            &part.headers,
+                            init_req.params.protocol_version.as_str(),
+                            Some(req.id.clone()),
+                        )?;

Source: GitHub commit dfa7fd6. The patch moves message-type and protocol-version validation ahead of create_session(), so no session state is allocated until the request is confirmed to be a valid initialization.

Detection Methods for CVE-2026-63128

Indicators of Compromise

  • Sustained growth in the rmcp server's resident memory without a corresponding increase in active clients.
  • Repeated JSON-RPC POST requests to the Streamable HTTP endpoint that lack a session identifier header.
  • HTTP 4xx responses referencing initialization errors or protocol version mismatches from a small set of source addresses.
  • Increasing p99 latency on legitimate MCP client requests correlated with request volume from unknown peers.

Detection Strategies

  • Instrument LocalSessionManager.sessions size and alert when the entry count exceeds the count of authenticated clients.
  • Parse reverse-proxy access logs for POSTs to the MCP endpoint that return validation errors, and aggregate by source IP.
  • Compare process RSS growth against a baseline; flag monotonic growth patterns typical of resource leaks.

Monitoring Recommendations

  • Export session-map cardinality and lock-wait metrics from the rmcp process to your metrics backend.
  • Enforce per-source request rate limits at the reverse proxy or load balancer fronting the MCP server.
  • Forward web-tier access logs and process telemetry to a centralized data lake for correlation and long-term retention.

How to Mitigate CVE-2026-63128

Immediate Actions Required

  • Upgrade the rmcp crate to version 2.0.0 or later and rebuild all dependent services.
  • Restrict network access to Streamable HTTP MCP endpoints to trusted clients using firewall or service-mesh policy.
  • Restart affected rmcp processes to release any leaked session state accumulated prior to patching.

Patch Information

The fix is shipped in rmcp release v2.0.0 via pull request #934. The patched handle_post validates the JSON-RPC message type and the MCP-Protocol-Version header before calling create_session(). Full remediation details are in GHSA-9pj6-vhgr-3mwh.

Workarounds

  • Place the rmcp Streamable HTTP endpoint behind an authenticating reverse proxy that rejects unauthenticated POSTs.
  • Apply strict per-IP rate limiting on the MCP endpoint to slow session-table growth from a single source.
  • Schedule periodic restarts of the rmcp server process to reclaim leaked session memory until the patched version is deployed.
bash
# Update Cargo.toml to the fixed version
cargo update -p rmcp --precise 2.0.0
cargo build --release

# Verify the resolved version
cargo tree -p rmcp | head -n 1

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.