dynoxide: DNS rebinding and cross-origin CSRF via MCP HTTP transport
Date: 2026-05
Affected: npm/dynoxide, rust/dynoxide-rs
Attack vector: other
Category: vulnerability-disclosure
Severity: High
CWE: CWE-346
CWE-350
CWE-352
CVSS: 7.5 (CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:H/I:H/A:H)

## Summary dynoxide's MCP HTTP transport was vulnerable to DNS rebinding via its transitive `rmcp` dependency, plus a related cross-origin CSRF gap. A malicious web page could make the user's browser send requests to a local `dynoxide mcp --http` or `dynoxide serve --mcp` server with a non-loopback `Host` header, which the server would then process. Affects 0.9.3 to 0.9.12. The stdio transport (`dynoxide mcp` without `--http`, which is the default) is not affected. ## Impact If a user is running `dynoxide mcp --http` (or `dynoxide serve --mcp`) on their machine and then visits a malicious web page, the attacker's JavaScript can call any MCP tool exposed by the running dynoxide instance. Reachable tools include reads (`get_item`, `query`, `scan`, `batch_get_item`, `describe_table`, `list_tables`) and writes (`put_item`, `update_item`, `delete_item`, `create_table`, `batch_write_item`). Any data in tables that the local dynoxide instance has access to can be read, modified, or destroyed. ## Patches dynoxide 0.9.13 closes both the named CVE and a related cross-origin CSRF gap: 1. **DNS rebinding (the named CVE).** `rmcp` is upgraded from 1.1.1 to 1.6.0. rmcp 1.4+ ships a default Host-header allowlist (`["localhost", "127.0.0.1", "::1"]`) which rejects requests carrying any other Host header with a 403. 2. **Defence in depth.** Explicit `allowed_hosts` and `allowed_origins` lists are now set on `StreamableHttpServerConfig` directly. The Host allowlist protects against a


Mitigations:

Architectural layers (MAESTRO):