May 18, 2026·6 min read·43 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
A critical memory handling vulnerability exists in the pageant crate, a workspace component of the Rust-based russh SSH client library, during communication with the PuTTY Pageant SSH agent on Windows systems. Prior to version 0.2.3, the library's shared memory parsing logic blindly trusted a peer-controlled, 32-bit big-endian response length field. This allows local attackers running within the same user session to trigger out-of-bounds reads or execute an out-of-memory crash of the client application.
A validation bypass vulnerability exists in Fastify web framework prior to version 5.12.2. The flaw stems from shallow normalization of header validation schemas, which fails to lowercase nested or conditional schema rules (like JSON Schema dependencies or dependentRequired) defined in mixed or canonical casing. Consequently, because Node.js normalizes incoming HTTP request headers to lowercase, the compiled validator fails to match these headers against the un-normalized mixed-case schema triggers, silently skipping conditional checks and allowing unauthenticated attackers to bypass authorization or security headers.
CVE-2026-84469 is a high-severity request validation bypass vulnerability in the Fastify Node.js web framework. In versions prior to 5.12.2, Fastify uses loose truthiness checks to decide whether to compile request schemas. When a component (such as the body) is explicitly configured with a boolean 'false' schema—which under JSON Schema Draft 7 acts as a 'deny-all' constraint—Fastify's internal logic evaluates this as a falsy value and skips compilation entirely. This allows unauthenticated remote attackers to send arbitrary payloads to these endpoints, bypassing validation checks and directly executing backend route handlers.
An authentication bypass vulnerability in the Fastify web framework allows remote attackers to access private custom not-found handlers by submitting requests with malformed URLs. This bypasses the typical request lifecycle and its associated authorization hooks.
An API contract mismatch in the Fastify web framework allows remote attackers to bypass schema validation when asynchronous schema validators are used. When a route uses async validation, the validator resolves with the raw request body. If the body contains a root-level key named 'value', the validation runner interprets this as a synchronous wrapper envelope, extracting and promoting the unvalidated nested content to the root level of request.body.
An improper neutralization of input during web page generation (CWE-79) vulnerability exists in the server-side rendering JSX engine (hono/jsx) of the Hono web framework prior to version 4.13.7. The flaw enables unauthenticated remote attackers to execute arbitrary JavaScript in the victim's browser context by supplying unescaped HTML characters into user-controlled fields rendered within specific boundary components, context providers, or direct server-side utilities.