You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 5bf5c32
Browse filesBrowse the repository at this point in the historyBrowse files
fix: enforce Host allow-list on HTTP transport to block DNS rebinding (#340)
* fix: enforce Host allow-list on HTTP transport to block DNS rebinding
The HTTP transport's DNS-rebinding guard only checked that the request
Origin hostname equalled its Host hostname. That is self-consistency
between two attacker-controlled values, not a trust decision: after DNS
rebinding a malicious page sends requests where both headers carry the
attacker hostname, so the check passed and the browser reached /mcp and
could execute SQL against the configured database.
Replace the equality check with an explicit Host allow-list (the real
rebinding defense), validated on every request — including those with no
Origin, since a rebound same-origin POST may omit it. Origin, when
present, must also be on the list so an untrusted origin is never
reflected into Access-Control-Allow-Origin.
The allow-list always includes loopback. On a wildcard bind (0.0.0.0/::)
the machine's own hostname and external IPs are auto-allowed via
getSelfHosts(), so local and by-IP access keep working with no config;
this is safe because a rebound request carries the attacker's hostname,
never the victim machine's own name/IP. Operators add other names (e.g. a
reverse-proxy/public DNS name) with --allowed-hosts / DBHUB_ALLOWED_HOSTS,
or "*" to disable the check when fronted by their own auth/proxy. The
resolved list is logged at startup.
Closes GHSA-fm8p-53ww-hf6w, GHSA-fp99-xwp4-hv8q, GHSA-qvg2-3c48-77mx.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* fix: address review — harden normalizeHost, doc IPv6 brackets, dedupe test
- normalizeHost(): reject crafted authority strings (e.g. "evil.com/foo",
"evil.com@host") via INVALID_HOST_CHARS, mirroring Host-header validation
so an operator typo cannot silently broaden the allow-list. Add a test.
- Capture getSelfHosts() once in the round-trip test (OS interface
enumeration can change between calls → flaky).
- Docs/.env.example: list loopback IPv6 as [::1] to match the bracketed
form the allow-list actually compares against.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
-`--allowed-hosts`: Comma-separated extra hostnames accepted in the HTTP `Host`/`Origin` headers, for DNS-rebinding protection (env `DBHUB_ALLOWED_HOSTS`). Loopback is always allowed; on a wildcard bind (`0.0.0.0`/`::`) this machine's hostname and IPs are auto-allowed so local/by-IP access needs no config. Set the flag for other names (e.g. a reverse-proxy/public DNS name); use `*` to disable the check when fronted by your own auth/proxy. See `buildAllowedHosts`/`getSelfHosts` in `src/utils/cross-origin.ts`.
124
126
-`--config`: Path to TOML configuration file
125
127
-`--demo`: Use bundled SQLite employee database
126
128
-`--readonly`: Restrict to read-only SQL operations (deprecated - use TOML configuration instead)
> The HTTP transport defaults to `--host 0.0.0.0`, exposing DBHub on every network interface. For production, bind to `127.0.0.1` and front DBHub with a reverse proxy (nginx/Caddy) or firewall — DBHub does not authenticate HTTP clients.
96
+
>
97
+
> The HTTP transport also has built-in DNS-rebinding protection: it only accepts requests whose `Host` is loopback, this machine's own hostname/IPs, or a name you allow via [`--allowed-hosts`](https://dbhub.ai/config/command-line#allowed-hosts). If a client behind a reverse proxy or custom DNS name gets a `403`, add that hostname with `--allowed-hosts`.
96
98
97
99
See [Command-Line Options](https://dbhub.ai/config/command-line) for all available parameters.
0 commit comments