CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



GHSA-FVH2-GM75-J4J7
8.80.02%

CVE-2026-42559: DNS Rebinding and CSRF in Model Context Protocol (MCP) HTTP Transport

Amit Schendel
Amit Schendel
Senior Security Researcher

May 18, 2026·6 min read·4 visits

PoC Available

Executive Summary (TL;DR)

A missing Host header validation in the rmcp HTTP transport allows attackers to execute arbitrary MCP tools on local dynoxide instances via DNS rebinding, leading to unauthenticated local database access.

The Model Context Protocol (MCP) Rust SDK (`rmcp`), a transitive dependency of the `dynoxide` database proxy, contains a high-severity vulnerability in its streamable HTTP server transport. The component fails to properly validate incoming HTTP `Host` headers, permitting DNS rebinding and Cross-Origin Request Forgery (CSRF) attacks against locally running database proxies.

Vulnerability Overview

The vulnerability resides in the rmcp crate, which provides the official Rust SDK for the Model Context Protocol (MCP). The dynoxide database proxy utilizes this crate to expose DynamoDB-compatible database operations via an MCP interface. The flaw specifically affects the StreamableHttpServer transport layer, which is enabled when users run dynoxide with the --http or --mcp flags.

The core issue is classified as CWE-346 (Origin Validation Error) and CWE-350 (Reliance on Reverse DNS Resolution for a Security-Critical Action). The HTTP transport server accepts incoming requests without verifying that the Host header corresponds to the expected local loopback address. This omission violates secure-by-default principles for local daemons.

Because the server listens on a local interface but fails to restrict the origin of the requests it processes, it exposes the local application to web-based attacks. An external attacker can interact with the local service by leveraging the browser of a user running the vulnerable daemon. The default stdio transport remains unaffected because it does not rely on HTTP communication.

Root Cause Analysis

The fundamental flaw exists within the request routing and validation logic of the rmcp crate's streamable HTTP server. Prior to version 1.4.0, the Tower service layer constructed the HTTP transport without implementing any middleware to validate the Host header of incoming HTTP requests. The server processed any well-formed HTTP request directed to its bound port, regardless of the target domain specified by the client.

Modern web browsers enforce the Same-Origin Policy (SOP) to prevent a website from making arbitrary authenticated requests to a different domain. Browsers also prevent client-side JavaScript from modifying security-critical headers, including the Host header. However, the SOP operates based on the domain name, not the underlying IP address. If a domain name dynamically resolves to a different IP address, the browser continues to send the original domain name in the Host header.

When the rmcp server receives a request resulting from a DNS rebinding attack, the Host header contains the attacker's domain (e.g., attacker.com), while the destination IP is 127.0.0.1. The lack of Host validation allows the server to parse the request, execute the underlying MCP tool, and return the result. The browser then delivers this response back to the malicious JavaScript, completing the unauthorized data extraction or modification.

Code Analysis

The fix was introduced in rmcp commit 8e22aa2de28df5a285eed87c11cd89bf15fa90d3. The patch implements a dedicated Tower middleware function to intercept and validate requests before they reach the MCP tool execution context. The key addition is the validate_dns_rebinding_headers function in crates/rmcp/src/transport/streamable_http_server/tower.rs.

// Patched code snippet from tower.rs
fn validate_dns_rebinding_headers(
    headers: &HeaderMap,
    config: &StreamableHttpServerConfig,
) -> Result<(), BoxResponse> {
    let host = parse_host_header(headers)?;
    // The patch enforces validation against an explicit allowlist
    if !host_is_allowed(&host, &config.allowed_hosts) {
        return Err(forbidden_response("Forbidden: Host header is not allowed"));
    }
    Ok(())
}

The StreamableHttpServerConfig now enforces a default Host allowlist containing ["localhost", "127.0.0.1", "::1"]. Any request with a Host header not matching this list is rejected with an HTTP 403 Forbidden response. This directly neutralizes the DNS rebinding vector.

Additionally, dynoxide version 0.9.13 implements defense-in-depth by upgrading the rmcp dependency and adding explicit allowed_hosts and allowed_origins checks. The Origin check mitigates a secondary CSRF vector where a malicious page could attempt to issue requests to the exact loopback IP using fetch with mode: 'no-cors'. The combined Host and Origin validation ensures complete protection against cross-origin interactions.

Exploitation Methodology

Exploitation requires the victim to run the vulnerable dynoxide server locally with the HTTP transport enabled. The attacker then lures the victim to a malicious website. The exploitation chain relies entirely on standard browser behavior and DNS infrastructure.

The attacker provisions a domain, such as attacker.com, and configures the authoritative name server to respond with a very short Time-To-Live (TTL) record. The initial DNS A record points to an external server hosting the malicious payload. The victim's browser resolves the domain, connects to the external server, and executes the JavaScript payload.

Immediately after serving the payload, the attacker's name server updates the A record for attacker.com to point to 127.0.0.1. The JavaScript payload waits for the initial DNS cache to expire, then issues an HTTP POST request to http://attacker.com:<dynoxide_port>/. Because the domain now resolves to localhost, the browser routes the request to the local dynoxide instance.

The local service receives the request, ignoring the Host: attacker.com header. It processes the JSON-RPC payload, which executes DynamoDB-compatible queries against the victim's local database. The response is passed back to the malicious JavaScript, which then exfiltrates the database contents to the attacker's infrastructure.

Impact Assessment

A successful exploit grants the attacker the ability to execute any MCP tool exposed by the local dynoxide server. The impact is directly tied to the permissions of the dynoxide instance and the data stored within the accessible DynamoDB tables. The attacker acts with the same privileges as the victim running the service.

The attacker achieves arbitrary data exfiltration by invoking tools such as get_item, query, scan, and batch_get_item. This allows the silent extraction of sensitive local development data, credentials, or proprietary schema designs. The attack is entirely unauthenticated from the perspective of the local service.

Furthermore, the attacker can execute destructive operations. By calling put_item, update_item, delete_item, or batch_write_item, the attacker can manipulate database records. Schema manipulation is also possible via create_table and describe_table. The CVSS v3.1 score of 8.8 reflects the high confidentiality, integrity, and availability impact, offset only by the requirement for user interaction (visiting the malicious site).

Remediation and Mitigation

The primary remediation strategy is to upgrade all dependent components to their respective patched versions. Developers utilizing the rmcp crate directly must update their dependency to version 1.4.0 or later. Users operating the dynoxide proxy must upgrade to version 0.9.13, which incorporates the patched rmcp dependency and introduces necessary Origin validation logic.

Organizations should verify their dependency trees to ensure no transitive inclusion of rmcp < 1.4.0 remains. For Rust projects, executing cargo tree | grep rmcp will identify vulnerable versions in the compilation graph. Node.js users running dynoxide via npm must ensure the updated package is pulled into their environments.

If immediate patching is not feasible, users must disable the HTTP transport mechanism. Running dynoxide mcp invokes the default stdio transport, which is immune to web-based attacks. Administrators must avoid passing the --http or --mcp flags to dynoxide serve until the software is fully updated.

Official Patches

nubo-dbGitHub Advisory for dynoxide
modelcontextprotocolGitHub Advisory for rmcp

Fix Analysis (1)

Technical Appendix

CVSS Score
8.8/ 10
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H
EPSS Probability
0.02%
Top 95% most exploited

Affected Systems

dynoxide-rs (crates.io)dynoxide (npm)rmcp (Model Context Protocol Rust SDK)

Affected Versions Detail

Product
Affected Versions
Fixed Version
dynoxide
nubo-db
0.9.3 - 0.9.120.9.13
rmcp
modelcontextprotocol
< 1.4.01.4.0
AttributeDetail
CVSS Score8.8
EPSS Score0.00018
CWE IDCWE-346, CWE-350
Attack VectorNetwork (DNS Rebinding)
Exploit StatusProof of Concept
ImpactData Exfiltration and Manipulation

MITRE ATT&CK Mapping

T1189Drive-by Compromise
Initial Access
T1190Exploit Public-Facing Application
Initial Access
CWE-346
Origin Validation Error

Origin Validation Error and Reliance on Reverse DNS Resolution

Vulnerability Timeline

Fix commit merged into modelcontextprotocol/rust-sdk
2026-04-01
CVE-2026-42559 published by GitHub
2026-05-14
GHSA-FVH2-GM75-J4J7 published for dynoxide
2026-05-18

References & Sources

  • [1]NVD CVE Record: CVE-2026-42559
  • [2]RustSec Advisory: RUSTSEC-2026-0140

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.