Cartographic attack-surface map showing one hostname route changing from a public web server to a local MCP database endpoint.

The Browser Changed the Address: DBHub DNS Rebinding to SQL

The first request failed exactly as expected: 403 Forbidden. The browser claimed attacker.example as its origin while the target identified itself as localhost:8080. DBHub saw the mismatch and closed the door.

Then one detail changed. Not the JavaScript. Not the MCP method. Not the database query. Only the Host header. When both Origin and Host said dbhub-rebind.example, DBHub 0.22.4 returned its tool inventory and executed a harmless SQL canary in my loopback lab. Version 0.22.5 rejected the same request shape.

That small difference captures CVE-2026-61742: an attacker-controlled website could use DNS rebinding to drive an unauthenticated DBHub HTTP transport from a victim’s browser, without prompt injection, model output, or a compromised MCP client.[1]

The check that looked reasonable

DBHub exposes database operations as MCP tools. Its default transport is stdio, but HTTP mode is documented for clients that need a network endpoint. In affected releases through 0.22.4, the HTTP middleware tried to stop hostile browser origins by extracting the hostname from Origin, extracting the hostname from Host, and requiring equality.[1]

Host: dbhub-rebind.example:8080
Origin: http://dbhub-rebind.example

originHost === host  // true

The comparison answers the wrong question. It proves that two request fields are self-consistent. It does not prove that either value belongs to a trusted deployment.

DNS rebinding exploits that distinction. The victim first resolves an attacker-owned hostname to the attacker’s web server and loads JavaScript. After the DNS answer changes, the same hostname resolves to a loopback or internal address reachable from the victim’s browser. The browser still sees the same origin tuple. The network destination has moved underneath it.

DNS rebinding flow showing an attacker-controlled hostname moving from a public server to a local DBHub MCP endpoint, followed by measured 0.22.4 and 0.22.5 lab results.
The vulnerable control checked agreement between attacker-controlled values. The fixed control checks both values against an explicit trust set.

A browser-origin pivot, not an AI exploit

The attack chain matters because it bypasses the defenses teams usually associate with agent security:

  1. A victim visits an attacker-controlled hostname on the DBHub HTTP port.
  2. The page loads while DNS points to the public attacker server.
  3. The hostname is rebound to a victim-accessible DBHub address.
  4. Browser JavaScript sends JSON-RPC to /mcp. Both Host and Origin retain the attacker hostname.
  5. The vulnerable equality check passes and reflects that origin in Access-Control-Allow-Origin.
  6. The page invokes tools/list or tools/call, reads the response, and can return data through ordinary browser egress.

No LLM needs to interpret hostile content. No approval dialog needs to be fooled. This is a browser-to-service authorization failure in an MCP deployment. It complements the broader trust-boundary model in MCP Security: How to Secure Agents, Tools, and Servers, but the entry point is lower in the stack: HTTP authority and name resolution.

Operationally, the browser becomes a network deputy. It can reach loopback, a developer VLAN, a VPN route, or an internal subnet that the attacker cannot access directly. If DBHub holds a production DSN, the effective authority is determined by exposed tools and database credentials, not by the apparent locality of port 8080.

What the loopback lab proved

I reproduced the post-rebinding request shape on September 28, 2026, using the packaged demo database and loopback only. No external rebinding service was used. The harness selected ephemeral ports, launched each version, issued one mismatch control, then sent identical rebind-shaped tools/list and read-only execute_sql requests.

# Isolated lab target, not a third-party service
npx -y @bytebase/[email protected] \
  --transport http --port "$PORT" --demo

# TCP destination stays 127.0.0.1; headers simulate the post-rebind shape
Host: dbhub-rebind.example:$PORT
Origin: http://dbhub-rebind.example

{"jsonrpc":"2.0","id":"read","method":"tools/call",
 "params":{"name":"execute_sql",
 "arguments":{"sql":"select 'LOCAL_LAB_CANARY' as proof"}}}
VersionMismatched Origin/HostRebind-shaped tools/listSQL canary
0.22.4403200200, canary returned
0.22.5403403403

The result isolates the security decision. It does not simulate DNS timing, browser resolver behavior, or production routing. It demonstrates that once a browser produces the accepted post-rebinding headers, 0.22.4 dispatches MCP methods while 0.22.5 blocks them. That is the claim the lab can support, and no more.

The patch replaces consistency with policy

The fix merged in DBHub pull request 340 validates every Host against an allow-list, including requests that omit Origin. If Origin exists, it must also belong to the allowed set before it can be reflected.[2][3] Loopback names remain allowed. Operators can add reverse-proxy or deployment names through --allowed-hosts or DBHUB_ALLOWED_HOSTS.

This is a better security invariant: the server decides which names represent it. An attacker can make DNS and browser headers agree, but cannot add an arbitrary hostname to the server’s configured trust set.

Do not stop at 0.22.5. DBHub 0.22.6 also addresses a separate failure where readonly = true depended on a SQL classifier while the intended database-level enforcement was not wired into normal configuration. The advisory documents side-effecting SELECT functions and adds engine-level controls such as PostgreSQL BEGIN READ ONLY and SQLite PRAGMA query_only.[5][6] The combined lesson is familiar from MCP tools and permissions in practice: a tool label is not a database boundary.

Detection and defense

Patch first. Upgrade to 0.22.6 or later.[4] Bind HTTP transport to loopback when remote access is unnecessary. If a reverse proxy is required, authenticate there and keep an explicit DBHub host allow-list. Avoid the wildcard --allowed-hosts "*" unless an upstream control is genuinely enforcing both authentication and destination policy.[2]

Reduce database authority. Use a dedicated DSN with schema-level grants, statement timeouts, and no server-file, extension, or program-execution privileges. Read-only enforcement should exist in the database session, not only in an MCP tool definition or keyword parser. This also limits damage from prompt injection and compromised clients, attack paths explored in enterprise AI attack chains.

Hunt the boundary crossing. Useful signals are relational:

  • HTTP requests to /mcp whose Host is not an approved deployment name.
  • Browser-like Origin, Sec-Fetch-Site, and user-agent headers reaching a service normally called by an MCP client.
  • Bursts of tools/list followed by tools/call from an unexpected workstation or developer endpoint.
  • DNS answers for one hostname moving from a public address to loopback, RFC 1918, link-local, or another internal range within a short window.
  • Database sessions from DBHub enumerating metadata and then issuing atypical queries or producing unusual result volume.

A single control will miss variants. Host allow-listing prevents the documented rebinding shape. Authentication protects the dispatch layer. Network binding narrows reachability. Database least privilege constrains impact. DNS, HTTP, MCP, and database telemetry together explain the sequence.

Strategic takeaway

MCP did not create DNS rebinding, but it raises the value of the service behind the browser boundary. A local endpoint may now hold a compact catalog of high-level operations backed by privileged credentials. That makes old web assumptions operationally expensive.

The detail to remember is not the hostname trick. It is the decision error. Equality between attacker-influenced values is not authorization. When an MCP server crosses from stdio to HTTP, treat host identity, client authentication, tool capability, and database authority as separate controls. If any one of them is expected to stand in for the others, the attack path is already forming.

Sources

  1. DBHub advisory for CVE-2026-61742, published September 24, 2026.
  2. DBHub pull request 340, Host allow-list fix and validation rationale.
  3. Fix commit 5bf5c32, merged June 24, 2026.
  4. DBHub v0.22.6 release, published July 10, 2026.
  5. DBHub read-only enforcement advisory, published September 24, 2026.
  6. DBHub pull request 342, engine-level read-only enforcement.

💜 Enjoyed this content? Support the blog with USDT (TRC20):

TX7obcjHQbDUXb4mGqoASEu1QFTKT2CFGG

View support page

Paulo Rigonato

Security Engineer | Red Team | Pentest

Offensive security specialist with experience in assessments, pentesting, and Red Team operations. He works in enterprise cybersecurity and continues to share knowledge through this blog.

Certifications: OSCP | eWPTXv2 | ITILv4

💻 GitHub 🔗 LinkedIn

Similar Posts