Summary
get_ws_url() (src/browser_harness/daemon.py:104) falls back to scanning the default Chrome profiles and then probing ports 9222/9223 whenever BU_CDP_URL/BU_CDP_WS is unset. For a named/managed daemon (one started via ensure_daemon(name=...) to drive a dedicated, isolated automation Chrome), that fallback is a footgun: on any daemon respawn where the env doesn't carry BU_CDP_URL, the daemon silently attaches to the user's daily-driver Chrome — or pops the chrome://inspect "Allow remote debugging" dialog on Chrome 136+.
Why it matters
A managed caller sets BU_NAME + BU_CDP_URL to pin a daemon to an isolated Chromium. But ensure_daemon() re-runs on every helper invocation, and on a respawn (parent restart, session teardown, zombie Chromium) a caller that carried only BU_NAME loses the pin. get_ws_url() then:
daemon.py:126 — scans PROFILES (the default user-data-dirs), attaching to the user's real Chrome;
daemon.py:154 — probes 9222/9223, silently attaching to whatever is listening there.
Today this only appears safe because Chrome 136+ gates the default profile behind the "Allow" dialog — i.e. it fails closed by accident. If the user has a pre-authorized debug Chrome on 9222, it drives it silently. This bit us as a real cross-project daily-driver breach (a downstream broker's ADR-022 firewall).
Proposed fix
An opt-in fail-closed guard so a managed daemon never falls back to local discovery. Either:
- honor a
BU_NO_LOCAL_FALLBACK=1 env, or
- infer it when the daemon was started with a
name (managed daemons are, by definition, pinned).
When set, and BU_CDP_URL/BU_CDP_WS is absent or unreachable, get_ws_url() should raise rather than reach the PROFILES scan (daemon.py:126) or the 9222/9223 probe (daemon.py:154) — a loud, honest failure that says "the pinned endpoint is gone, relaunch the session," never a silent attach to the user's Chrome.
Related
Distinct from #291 (that was a /json/version 404 fallback for the BU_CDP_URL happy path). This is about refusing the default-profile fallback entirely for pinned daemons.
Summary
get_ws_url()(src/browser_harness/daemon.py:104) falls back to scanning the default Chrome profiles and then probing ports 9222/9223 wheneverBU_CDP_URL/BU_CDP_WSis unset. For a named/managed daemon (one started viaensure_daemon(name=...)to drive a dedicated, isolated automation Chrome), that fallback is a footgun: on any daemon respawn where the env doesn't carryBU_CDP_URL, the daemon silently attaches to the user's daily-driver Chrome — or pops thechrome://inspect"Allow remote debugging" dialog on Chrome 136+.Why it matters
A managed caller sets
BU_NAME+BU_CDP_URLto pin a daemon to an isolated Chromium. Butensure_daemon()re-runs on every helper invocation, and on a respawn (parent restart, session teardown, zombie Chromium) a caller that carried onlyBU_NAMEloses the pin.get_ws_url()then:daemon.py:126— scansPROFILES(the default user-data-dirs), attaching to the user's real Chrome;daemon.py:154— probes9222/9223, silently attaching to whatever is listening there.Today this only appears safe because Chrome 136+ gates the default profile behind the "Allow" dialog — i.e. it fails closed by accident. If the user has a pre-authorized debug Chrome on 9222, it drives it silently. This bit us as a real cross-project daily-driver breach (a downstream broker's ADR-022 firewall).
Proposed fix
An opt-in fail-closed guard so a managed daemon never falls back to local discovery. Either:
BU_NO_LOCAL_FALLBACK=1env, orname(managed daemons are, by definition, pinned).When set, and
BU_CDP_URL/BU_CDP_WSis absent or unreachable,get_ws_url()shouldraiserather than reach thePROFILESscan (daemon.py:126) or the9222/9223probe (daemon.py:154) — a loud, honest failure that says "the pinned endpoint is gone, relaunch the session," never a silent attach to the user's Chrome.Related
Distinct from #291 (that was a
/json/version404 fallback for theBU_CDP_URLhappy path). This is about refusing the default-profile fallback entirely for pinned daemons.