fix(security): bind the extension control channel to loopback and gate its handshake#53
Merged
Merged
Conversation
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
fix(security): bind the extension control channel to loopback and gate its handshake
The WebSocket server was created as
new WebSocket.Server({ port: WS_PORT }).With no
host, Node listens on all interfaces, so the browser-automationcontrol channel was reachable from the LAN. The connection handler hands
chromeExtensionSocketto whoever connects last, closing the previous socket,so any reachable peer could evict the real extension, receive every automation
command the MCP server issues, and return fabricated results to the model.
Two changes:
same machine and the optional ngrok tunnel forwards the HTTP port only, so
nothing legitimate needs this off-host.
user visits can also reach 127.0.0.1. Browsers send Origin on a cross-origin
WebSocket handshake, so page-initiated connections are rejected while
extension-scheme origins and local non-browser clients are allowed.
Verified against a running server:
bind address 127.0.0.1:5711 (was *:5711)
loopback + chrome-extension:// ACCEPTED
loopback + no origin ACCEPTED
loopback + https://evil.example REJECTED 403
LAN 10.x.x.x ECONNREFUSED
Not addressed here: the HTTP/SSE server still listens on all interfaces with
Access-Control-Allow-Origin: *. That one needs a separate decision becauseremote MCP clients and the tunnel path may depend on it.
Co-Authored-By: Claude noreply@anthropic.com