May 18, 2026·6 min read·28 visits
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.
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.
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.
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 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.
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).
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.
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H| Product | Affected Versions | Fixed Version |
|---|---|---|
dynoxide nubo-db | 0.9.3 - 0.9.12 | 0.9.13 |
rmcp modelcontextprotocol | < 1.4.0 | 1.4.0 |
| Attribute | Detail |
|---|---|
| CVSS Score | 8.8 |
| EPSS Score | 0.00018 |
| CWE ID | CWE-346, CWE-350 |
| Attack Vector | Network (DNS Rebinding) |
| Exploit Status | Proof of Concept |
| Impact | Data Exfiltration and Manipulation |
Origin Validation Error and Reliance on Reverse DNS Resolution
An integer truncation vulnerability (CWE-197) exists in SQLite before version 3.50.2 during the processing of aggregate queries with more than 32,767 distinct column references. This causes an internal 32-bit counter to truncate to a signed 16-bit integer, producing negative values that cause out-of-bounds heap operations in release builds.
An integer overflow vulnerability in the Windows kernel-mode HTTP driver (HTTP.sys) allows an unauthenticated remote attacker to execute arbitrary code with kernel privileges or cause a Denial of Service via a specially crafted sequence of HTTP request headers.
A memory corruption vulnerability exists in the FTS5 (Full-Text Search 5) extension of SQLite prior to version 3.53.2. An attacker can construct a malicious database file containing corrupt FTS5 page data. Querying this database triggers out-of-bounds reads and heap-based buffer overflows, potentially causing a crash or arbitrary code execution.
A mass assignment vulnerability (CWE-915) in n8n's self-service settings API endpoint (PATCH /me/settings) allows authenticated Single Sign-On (SSO) users to disable SSO enforcement for their accounts by injecting administrative parameters. This bypasses organizational identity provider controls and multi-factor authentication (MFA).
CVE-2026-55699 (also identified as GHSA-4gxm-v5v7-fqc4) is a critical path traversal and arbitrary directory deletion vulnerability in the pnpm package manager. The issue exists because the manifest validation process fails to prevent relative path segments within the package 'bin' keys. When a malicious package containing structured path traversal markers is globally installed and later manipulated, pnpm resolves the target paths through path.join() and passes the resolved paths to a recursive deletion function, resulting in arbitrary directory removal.
A path traversal vulnerability in pnpm stage download allows malicious registries or compromised package manifests to overwrite arbitrary files on the victim's filesystem via unvalidated package name and version fields.