BUG BOUNTYFIELD MANUAL
Reusable module
Markdown
0 / 6 checkedChecks last until this page reloads.

Browser extensions: message authority and document lifetime

Trace real page messages into extension capabilities and test sender identity, navigation races, permission changes and worker restarts.

Investigation sequence
  1. 01Identify installed release
  2. 02Map message channels
  3. 03Capture allowed action
  4. 04Change sender or document
  5. 05Confirm recipient and effect
  6. 06Restore profile

At each step: retain the control → record the observation → continue only while the next boundary is understood.

Used in these playbooks#

Setup and security invariant#

Use the scoped store release, a disposable browser profile and two controlled local web origins. Record extension ID/version, browser version, Manifest version and granted optional permissions. Keep a separate unpacked copy for source tracing; changing its manifest, ID or permission grants changes the reproduction assumptions. Seed one private marker and one public marker in the extension's supported lab data. Invariant: a page cannot borrow extension or native-host authority beyond the specific operation delegated to that page and document.

Procedure, controls and interpretation#

  1. Separate the message channels. Draw page → DOM event/content script → service worker → browser API/native host. Inventory window.postMessage, custom events, runtime.onMessage, external-message listeners and ports separately. An external-message allowlist does not control an ordinary content script forwarding page data. Use only the channel actually reachable from a normal page. Chrome documents that content scripts are a lower-trust context for extension messages. Message passing, external messaging configuration.

  2. Capture a legitimate request. Trigger one supported page action and record action name, input schema, browser-provided sender ID/origin, tab/frame/document and the protected operation. Distinguish browser-supplied metadata from fields named origin, sender, tabId or trusted inside the message body. A content-script sender ID identifying the extension does not establish that its forwarded page input was authorized. Keep sensitive values out of the page until its entitlement is established.

  3. Vary one authority dimension. Compare the valid page with the second controlled origin, a child frame, an unsupported action and a different known synthetic resource. Invoke through the product's real page listener; do not paste privileged extension APIs into its developer console. For a fetch broker, compare the intended public fixture with the protected marker destination and inspect who receives the response. Chrome's network guidance specifically warns against letting an untrusted sender choose arbitrary fetch destinations. Reuse browser trust and SSRF boundaries for URL normalization and redirect decisions. Extension network requests.

  4. Test document lifetime. Pause a local mock response, navigate the initiating tab to the second origin, then release the response. Observe whether the reply or permission decision follows the original document or merely a reused tab/frame. Include same-tab navigation and a child-frame case separately. Chrome exposes documentId and origin on message senders; those fields need browser-version-aware handling. The inference being tested is whether the product preserves the identity it authorized across an asynchronous gap. A dropped reply is a valid denied control. MessageSender, document-specific tab messaging.

  5. Restart and revoke. Let the service worker stop naturally or stop it through the local debugging UI; repeat the denied case after restart. Separately revoke an optional permission through supported browser controls. Record whether trusted state, grants or pending replies are re-created safely. Service-worker global variables are not durable storage. A debugging session can alter worker lifetime, so repeat the minimum case with developer tools closed. Service worker lifecycle.

  6. Confirm the capability. Record the actual returned marker or reversible operation. For native messaging, continue with desktop IPC; distinguish extension-to-user-process access from a demonstrated administrator boundary. Broad permissions, a public resource, or a rejected unknown action are not standalone findings.

Local command sheet#

These inspect an acquired lab copy without loading it or invoking browser APIs:

python3 -I -S -m json.tool ./extension/manifest.json
rg -n 'postMessage|addEventListener|onMessage|onConnect|externally_connectable' ./extension
rg -n 'sender\.|documentId|frameId|tabs\.(sendMessage|connect)|sendNativeMessage' ./extension
rg -n 'fetch\(|host_permissions|optional_host_permissions|storage\.(local|session)' ./extension

For each match, save an evidence row: initiating origin/document, message fields, trusted metadata, decision, receiving document and resulting capability. The source scan identifies routes to exercise; a match itself proves no reachability.

Completion checklist#

  • Allowed and denied origins produce the expected baseline decisions.
  • The candidate works through the shipped page/content-script entry.
  • Body-supplied identities are distinguished from browser metadata.
  • Navigation and restart results include their event order.
  • Optional permission grants and user interaction are documented.
  • Remove local page fixtures and restore the disposable profile after retaining redacted evidence.

Vulnerability reverse references#

Nearby shared procedures#

Object, function, and property authorization · Authentication, recovery, federation, and session lifecycle · Trace input into queries, commands, and templates · Server-side fetching and network trust boundaries · Browser execution, cross-origin reads, and forged actions · Uploads, downloads, paths, archives, and XML · Workflow invariants, replay, idempotency, and races · REST, GraphQL, gRPC, WebSocket, and SSE permission parity