Skip to main content
BrowserTools captures whatever your browser sees — console output, request and response bodies, screenshots of a logged-in session. That is sensitive by definition, so 2.0 treats it that way. All captured data stays on your machine. It is never sent to any third-party service or API. The only thing that leaves the local connector is what your MCP client asks for, and your agent then sees.
Version 1.2.x and earlier contain known critical vulnerabilities. They are fixed in 2.0.0 by design changes, not patches — which is why 2.0 is a rewrite. If you are still on 1.x, upgrade now.

How 2.0 protects you

  • Loopback only. The connector binds 127.0.0.1 and refuses non-loopback addresses. In 1.x it bound 0.0.0.0, reachable by anyone on your network.
  • The extension never leaves loopback. 1.x scanned private network ranges and adopted whichever host answered with a known string — meaning anyone on shared Wi-Fi could receive your logs and screenshots. That scan is gone; the extension only ever contacts 127.0.0.1 and localhost.
  • Authenticated. The HTTP API requires a bearer token generated per run and stored in a 0600 file. The WebSocket accepts chrome-extension://, moz-extension:// and safari-web-extension:// origins only — any http(s) origin is rejected outright, because a browser sets Origin itself and a page therefore cannot forge one. The Host header is validated against DNS rebinding.
  • Nothing captured reaches a shell. Screenshot names are restricted to [A-Za-z0-9._/-] and resolved inside a fixed directory.
  • Credentials are scrubbed before storage — see below.
  • Headers are off by default, independently per direction, and storage values are withheld unless a tool explicitly asks for them.
  • Cookie access is an optional permission you grant from the panel, not something the extension holds by default.
  • Fewer permissions overall. <all_urls> and tabs are no longer in the extension’s default set.
These are covered by regression tests that assert the listener address, the absence of permissive CORS, rejection of page origins and foreign hosts, and that a path containing shell metacharacters is refused.

Redaction is layered, and best-effort

Credential scrubbing runs twice: in the browser before anything is truncated or transmitted, and again on the server before storage. The browser pass is the one that matters most — it means a recognised secret never crosses the socket at all. It covers credential-bearing headers, JWTs (including ones cut short by truncation), vendor session and client identifiers, cloud provider keys, and common password/token JSON fields.
Redaction is pattern-based, so it is not a guarantee. A bespoke or unrecognised token shape can still get through. Treat --no-redact as strictly for cases where you have decided the captured data is not sensitive.
Over-redaction is treated as a bug too. A false positive silently destroys the debugging information this tool exists to provide, so patterns are confirmed rather than assumed where a cheap check exists — a JWT candidate, for instance, is verified by decoding its header, because plenty of harmless data is also base64-encoded JSON. If you find a shape that leaks, or one that is being redacted when it should not be, both are worth reporting.
Seeing [REDACTED] in your logs is this tool protecting you, not your app misbehaving.

Known vulnerabilities in 1.x

All three are fixed in 2.0.0.
The connector bound 0.0.0.0, applied wildcard CORS, and performed no origin check or authentication on its WebSocket upgrade. A path value taken from a WebSocket message was interpolated into a shell command.Any web page the user visited — or anyone on the same network — could open the socket, impersonate the extension, and execute arbitrary commands as the user. Reported in issues #224, #232 and #233.Fixed by: binding loopback only and refusing non-loopback addresses; requiring a browser-extension Origin on the WebSocket upgrade; requiring a per-run bearer token on the HTTP API; validating the Host header; removing the AppleScript path entirely; and constraining screenshot names to a safe character set resolved inside a fixed directory.
The extension probed 192.168.0.x, 192.168.1.x, 10.0.0.x and 10.0.1.x across ports 3025–3035, and adopted the first host that returned a constant string — persisting it to settings. That string is a public identifier in a public repository, not a credential.Anyone on shared Wi-Fi could run a trivial HTTP server returning it and silently receive the developer’s console output, full request and response bodies, and screenshots, across restarts.Fixed by: removing the network scan entirely.
With no authentication and wildcard CORS, any visited page could read the console and network endpoints (including bodies and headers), force a screenshot, write arbitrary bytes to arbitrary paths, overwrite global settings, wipe captured data, and spawn headless Chrome instances.The settings endpoint also merged arbitrary keys from an unauthenticated request body into server settings, which allowed both memory exhaustion and injecting fabricated log entries that the developer’s AI agent would then read and act on.Fixed by: token-authenticated API, origin and host validation, an explicit settings allowlist with clamped ranges, and removal of caller-supplied filesystem paths.

Reporting a vulnerability

Please report privately through GitHub Security Advisories rather than opening a public issue. We aim to acknowledge within 72 hours. Include what the issue is, how to reproduce it, and what an attacker gains. Proof-of-concept code is welcome and speeds up triage considerably.