If you believe you've found a security issue in dynoxide, please report it privately rather than opening a public issue.
Use GitHub's private vulnerability reporting: https://github.com/nubo-db/dynoxide/security/advisories/new
I aim to acknowledge reports within 5 business days. Fix timelines depend on severity: critical issues affecting the loopback-only boundary, within 30 days; other confirmed issues, best effort, typically within 90 days.
dynoxide's MCP HTTP transport is intended for local single-user development, with an explicit opt-in for wider exposure. It is opt-in to begin with: the default dynoxide mcp uses stdio and has no network exposure. Only dynoxide mcp --http (or dynoxide serve --mcp) opens an HTTP listener.
The HTTP transport defends against two threats: direct-from-tooling callers (anyone who can reach the port) and browser-based cross-origin attacks (DNS rebinding, cross-origin CSRF).
dynoxide:
- Requires a bearer token on every request. Each
/mcprequest must carryAuthorization: Bearer <token>; a missing or wrong token returns an identical401(no oracle distinguishes the two). On a loopback bind with no token supplied, dynoxide generates one on first run, persists it to a per-user config file (mode0600on Unix; on Windows it lives under your per-user%APPDATA%, which other standard accounts cannot read), and prints client-config guidance. Supply your own with--token/--mcp-tokenorDYNOXIDE_MCP_AUTH_TOKEN. There is no rotation mechanism: to rotate, delete the persisted file (or change the env var) and restart. - Defaults to a loopback bind.
--host/--mcp-hostcan widen it, but a non-loopback bind will not start without an explicit token — auto-generation is loopback-only. - Validates the
Hostheader against a loopback allowlist (localhost,127.0.0.1,::1); anything else returns403.--allowed-host/--mcp-allowed-hostadds names for non-loopback by-name access. The auth check runs first, so a valid token holder who then spoofsHoststill gets403— the allowlist is defense-in-depth, not the primary control. - Validates the
Originheader when present, againsthttp://localhost,http://127.0.0.1, and any added hosts; anything else returns403. Native MCP clients (Claude Code, Cursor, the dynoxide CLI) don't send an Origin header and pass through unaffected.
With authentication in place, dynoxide is suitable for:
- Local development on a personal machine
- CI environments
- Dockerised and network-exposed deployments, provided a token is set and treated as a secret (passed via
DYNOXIDE_MCP_AUTH_TOKEN, not a flag, to keep it out of process listings and shell history)
A loopback-only escape hatch, --no-auth / --mcp-no-auth, disables authentication entirely; it refuses to start on a non-loopback bind. Use it only on a trusted single-user machine where no other local process is a concern.
The stdio transport is unaffected by all of the above — it is process-scoped and has no network surface.
See the Security Advisories tab.