#1136·gstack

security: switch cookie-import-browser CDP from TCP port to --remote-debugging-pipe

Author: garrytanCreated Apr 22, 2026Updated Sep 28, 2026

Context

The v20 App-Bound Encryption elevation path on Windows, deferred from the v1.6.0.0 security wave. See the updated comment block in browse/src/cookie-import-browser.ts around the --remote-debugging-port launch.

Problem

On Windows 10.15+ with ABE v20, a local same-user process cannot decrypt cookies by reading the SQLite DB directly — the DPAPI context is bound to the browser process. But the CDP debug port bypasses that: any same-user process can connect to http://127.0.0.1:<random-port>/json/list, find a page target's WebSocket URL, and call Network.getAllCookies inside Chrome to get decrypted values.

Today the port is randomized in [9222, 9321] and Chrome is killed in the finally block, but there's a window (typically 1-3 seconds while the CDP call is in flight) during which a concurrent same-user process can steal decrypted v20 cookies.

Fix direction

Switch --remote-debugging-port=<N> → --remote-debugging-pipe. Chrome then exposes the CDP transport over a parent/child stdio pipe instead of a TCP socket, eliminating the TCP surface entirely.

Work

  • Drop --remote-debugging-port from the Bun.spawn args in cookie-import-browser.ts around line 846.
  • Pass --remote-debugging-pipe + stdio: ['pipe', 'pipe', 'pipe', 'pipe', 'pipe'] (CDP uses fds 3+4).
  • Replace fetch(http://127.0.0.1:\${debugPort}/json/list) + WebSocket connection with a CDP client that reads/writes framed JSON on the pipe fds.
  • Playwright doesn't expose this transport out of the box. Either write a minimal CDP-over-pipe client (~200 lines) or find a library that supports it.

Acceptance

  • bun test passes, cookie-import flow still works on macOS and Linux.
  • Windows integration smoke test confirms v20 cookies are imported.
  • No TCP port opened for the debug transport.

Out of scope for this issue

  • Restructuring extractCookiesViaCdp for non-Chromium targets.
  • Switching the main browse daemon to pipe transport (separate concern).

Tracked from v1.6.0.0 security wave N2 non-goal.