gstack/extension
Garry Tan b3d477bbb5
fix(extension): deny token/port reads to content-script and foreign senders
background.js answered getPort — port, connected state, AND the browse
server auth token — to any sender that passed the type allowlist,
including content scripts running in web-page context and, behind only
the sender.id check, anything without extension-page provenance. The
getToken sender.tab restriction covered getToken alone, and only after
getPort had already handed out the token.

Single decision point now: extension/sender-auth.js classifies each
message type; the eight privileged types (getPort, setPort, getServerUrl,
getToken, fetchRefs, command, sidebar-command, getTabState) require an
own-extension-page sender (chrome-extension://<own id>/ URL, no
sender.tab, own sender.id). Denied senders get { error: 'unauthorized' }
and nothing else — never the token, never the port. Content-script flows
(elementPicked, pickerCancelled, inspectResult, openSidePanel) are
untouched, and the sidepanel/popup keep the getPort token field their
connect path reads. The policy mirrors the v1.63 server-side model:
AUTH_TOKEN is released only to the pinned extension Origin via
POST /extension-token, so the extension must not re-leak it to contexts
the server would never have trusted.

browse/test/extension-sender-auth.test.ts drives the real background.js
onMessage listener under a chrome stub with four sender shapes (own
extension page, own content script, foreign extension id, missing
sender.url) and pins that denied responses carry no token/port fields,
that a denied setPort never persists, that a denied command never
reaches the network, and that the inspector + tab-state flows keep
working. The helper is loaded via importScripts in the classic service
worker and require()-able from bun tests.

Contributed by @punksterlabs (PR #1822; reimplemented against the v1.63 POST /extension-token pinned-origin model).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-14 20:20:50 -07:00
..
icons feat: headed mode + sidebar agent + Chrome extension (v0.12.0) (#517) 2026-03-26 11:15:24 -06:00
background.js fix(extension): deny token/port reads to content-script and foreign senders 2026-08-14 20:20:50 -07:00
content.css feat: headed mode + sidebar agent + Chrome extension (v0.12.0) (#517) 2026-03-26 11:15:24 -06:00
content.js refactor: AI slop reduction with cross-model quality review (v0.16.3.0) (#941) 2026-04-10 17:13:15 -10:00
inspector.css feat: sidebar CSS inspector + per-tab agents (v0.13.9.0) (#650) 2026-03-30 12:51:05 -06:00
inspector.js refactor: AI slop reduction with cross-model quality review (v0.16.3.0) (#941) 2026-04-10 17:13:15 -10:00
manifest.json v1.63.0.0 feat: GStack 2 fork port wave — egress receipts, context-bill, sharded gate, /health fix (#2541) 2026-08-14 09:28:56 -07:00
popup.html feat: headed mode + sidebar agent + Chrome extension (v0.12.0) (#517) 2026-03-26 11:15:24 -06:00
popup.js feat: headed mode + sidebar agent + Chrome extension (v0.12.0) (#517) 2026-03-26 11:15:24 -06:00
sender-auth.js fix(extension): deny token/port reads to content-script and foreign senders 2026-08-14 20:20:50 -07:00
sidepanel-terminal.js v1.63.0.0 feat: GStack 2 fork port wave — egress receipts, context-bill, sharded gate, /health fix (#2541) 2026-08-14 09:28:56 -07:00
sidepanel.css v1.51.0.0 feat: $B memory diagnostic + 4 CDP-resource leak fixes (#1751) 2026-05-27 16:09:38 -07:00
sidepanel.html v1.51.0.0 feat: $B memory diagnostic + 4 CDP-resource leak fixes (#1751) 2026-05-27 16:09:38 -07:00
sidepanel.js v1.63.0.0 feat: GStack 2 fork port wave — egress receipts, context-bill, sharded gate, /health fix (#2541) 2026-08-14 09:28:56 -07:00