-
Notifications
You must be signed in to change notification settings - Fork 533
Description
Hey! Following up from #268 — the CSRF fix was solid, but I noticed the WebSocket endpoint still has a gap.
The verifyClient check does this:
return !origin || origin.startsWith('chrome-extension://');The problem is the !origin part — if there's no Origin header at all, the connection is allowed through. Node.js WebSocket clients don't send Origin by default, so any script on the machine can connect to ws://127.0.0.1:19825/ext and impersonate the extension:
const ws = new WebSocket('ws://127.0.0.1:19825/ext');
// connects successfully, full access, no auth neededSame goes for the HTTP side — X-OpenCLI: 1 blocks browsers nicely, but it's a hardcoded value in the source code, not a secret. Any local process that reads the repo knows to add it.
I think the cleanest fix would be generating a random token on first run (stored at ~/.opencli/token), and requiring it in the WebSocket handshake and HTTP requests. The extension and CLI can both read the file. Everything else gets rejected.
This matters more now that AI agents (Claude Code, Cursor, etc.) are running locally alongside tools like OpenCLI — the attack surface for local process impersonation is growing.