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)
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
- 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
- Upgrade nanobot to 0.3.0 or later (
pip install -U nanobot-ai). - Until you upgrade, set
token_issue_secret(ortoken) for the gateway so the bootstrap route is not open to any local caller, and stopnanobot gatewaywhen 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_bootstrapgated token issuance only on_is_localhost(connection)when no secret was setnanobot/webui/http_utils.py:is_localhost()looked only at the TCP peer addressnanobot/channels/websocket.py: the WebSocket upgrade checked the token andallow_frombut notOriginorHost
Fix
- 207813d ("tighten localhost bootstrap check") makes token issuance require a local browser request: a local TCP peer, a loopback
Hostheader 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
- Reported privately via GitHub PVR (GHSA-68pq-qxvf-p68w), with a suggested fix.
- Maintainer commits the fix (207813d).
- nanobot 0.3.0 released with the fix.
- Maintainer closes the advisory without publishing it.
- Public write-up; CVE requested from MITRE.
Credit
Finder: Aaron Elijah Mars of Aeon. Tool: Aeon.
References
- Fix commit: HKUDS/nanobot@207813d
- Fixed release: nanobot 0.3.0
- GitHub advisory: GHSA-68pq-qxvf-p68w (private; closed, not published)
- CVE: pending (requested from MITRE)
- Affected repository: HKUDS/nanobot