Security

nanobot: DNS rebinding to agent control via the WebUI gateway

nanobot WebUI gateway - DNS rebinding lets a web page mint a gateway token and drive the agent, including its shell tool (GHSA-68pq-qxvf-p68w)

PUBLISHED SEVERITY HIGHSTATUS PatchedGHSA-68pq-qxvf-p68w
Patched

Fixed in nanobot 0.3.0 (2026-07-25): the WebUI bootstrap route now also requires a loopback Host header and loopback forwarding headers before it issues a token. Track the fix at HKUDS/nanobot@207813d.

Product
nanobot (PyPI nanobot-ai) in HKUDS/nanobot
Affected versions
nanobot-ai before 0.3.0 (reviewed at commit 98916a3, 2026-06-21). Fixed in 0.3.0 (2026-07-25).
Severity
HIGH
Status
Patched
Weaknesses
  • CWE-350Reliance on Reverse DNS Resolution for a Security-Critical Action
  • CWE-346Origin Validation Error
  • CWE-1385Missing Origin Validation in WebSockets
The CWEs for this finding; the advisory also listed CWEs for other findings not covered here.
GitHub advisory
GHSA-68pq-qxvf-p68w
Private; closed by the maintainer, not published
CVE
Pending (requested from MITRE)
Published
Credit
Finder: Aaron Elijah Mars of Aeon. Tool: Aeon (https://www.aeon.fun).

What users should do now

  1. Upgrade nanobot to 0.3.0 or later (pip install -U nanobot-ai).
  2. Until you upgrade, set token_issue_secret (or token) for the gateway so the bootstrap route is not open to any local caller, and stop nanobot gateway when you are not using it.

Summary

nanobot gateway, the documented way to run the WebUI, listens on 127.0.0.1:8765. With no token or token-issue secret configured (the default), its bootstrap route hands out an API token to any request whose TCP peer is local, and nothing checked the Host or Origin header. DNS rebinding makes a visited web page look like a local peer, so the page could mint a token, open the WebSocket and send the agent messages. Because the agent has a shell tool, that is code execution on the user's machine.

Affected versions

nanobot-ai before 0.3.0 running nanobot gateway with the default settings (loopback bind, no token or token_issue_secret). Reviewed at commit 98916a3 (2026-06-21).

Impact

  • A web page the user visits can, after DNS rebinding, call GET /webui/bootstrap, read the returned API token, open the WebSocket with it and send messages that the agent turns into tool calls: shell commands, file access, web requests, reading session transcripts and creating cron jobs for persistence.
  • No interaction is needed beyond visiting the page while the gateway runs.

Browser mitigation. Chrome's Local Network Access prompt raises the bar when the user denies it. Other browsers were not verified.

The original report also contained other findings that are still being coordinated with the maintainer. They are not covered here.

Affected code

  • nanobot/webui/ws_http.py: _handle_bootstrap gated token issuance only on _is_localhost(connection) when no secret was set
  • nanobot/webui/http_utils.py: is_localhost() looked only at the TCP peer address
  • nanobot/channels/websocket.py: the WebSocket upgrade checked the token and allow_from but not Origin or Host

Fix

  • 207813d ("tighten localhost bootstrap check") makes token issuance require a local browser request: a local TCP peer, a loopback Host header and only loopback values in forwarding headers. Released in 0.3.0.

Detection (for defenders)

Look for gateway requests (port 8765 by default) whose Host header names something other than 127.0.0.1, localhost or [::1], and for bootstrap calls or agent sessions you did not start.

Timeline

  1. Reported privately via GitHub PVR (GHSA-68pq-qxvf-p68w), with a suggested fix.
  2. Maintainer commits the fix (207813d).
  3. nanobot 0.3.0 released with the fix.
  4. Maintainer closes the advisory without publishing it.
  5. Public write-up; CVE requested from MITRE.

Credit

Finder: Aaron Elijah Mars of Aeon. Tool: Aeon.

References