[Desktop][Chrome] Claimed user tab can be closed directly without a provenance/ownership check

Open 💬 0 comments Opened Jul 24, 2026 by aidawilliam41-ops

Environment

  • Windows 11 25H2, build 26200.8037
  • codex-cli 0.146.0-alpha.3.1
  • OpenAI bundled Chrome plugin 26.721.31836 (bundledContentVariant: unified)
  • Exact Codex Desktop app version: unavailable from the protected running process
  • Observed and rechecked: 2026-07-24

Summary

The Chrome Extension/browser-client allows a claimed pre-existing user tab to be closed directly without checking creation provenance, cleanup ownership, or explicit owner intent.

Claiming a user tab should grant temporary control, not transfer ownership of that tab for cleanup. The normal finalization path already distinguishes claimed user tabs from agent-created tabs and leaves claimed tabs open, but direct Tab.close() bypasses that lifecycle boundary.

A confirmed real incident closed a pre-existing authenticated user tab. The tab was later reopened. No credential compromise, data exfiltration, or loss of unsaved data was established.

Minimal reproduction

  1. Connect to the existing authenticated Chrome Extension/browser-client session.
  2. Obtain an already-open user tab from browser.user.openTabs().
  3. Claim that exact tab with browser.user.claimTab(tab).
  4. Observe that claim returns a normal controllable Tab.
  5. Invoke:

``js
await claimedTab.close()
``

  1. The pre-existing user tab closes through the runtime close_tab command.

Expected behavior

  • Claiming grants temporary control, not cleanup ownership.
  • Direct close of an external, claimed, restored, or unknown-provenance tab should fail closed unless the active owner request explicitly authorizes closing that exact tab or a frozen bounded tab set.
  • Normal session cleanup should release claimed tabs and leave them open, matching browser.tabs.finalize(...) behavior.
  • Agent-created tabs should remain eligible for ordinary cleanup.

Actual behavior and source evidence

  • Public Tab.close() is declared as close(): Promise<void> with no ownership or authorization parameter.
  • Public TabInfo exposes only id, title, and url; it does not expose creation provenance or cleanup ownership.
  • The claim handler records acquired tabs with lifecycle origin external.
  • The create handler records created tabs with lifecycle origin agent.
  • The direct close_tab handler validates only that tab_id is a positive integer and then calls the CDP close operation.
  • close_tab receives security classification {kind: "none"}.
  • The direct close path does not consult the available tab lifecycle record.
  • Bundled cleanup guidance already states that claimed user tabs are released from browser-session control and left open during finalization.

Lifecycle information therefore exists, but the direct close path does not enforce it.

Impact

A model or tool-routing error can close a user-owned authenticated tab, including a form, draft, or other unsaved browser state.

Instruction-only cleanup guidance reduces the probability of this mistake but cannot enforce the ownership boundary. The user should not have to trust that every model invocation remembers never to call a public close method on a claimed tab.

This report does not claim credential compromise or data exfiltration.

Current workaround

Never directly close protected or unknown-provenance tabs through API, CDP, script, or UI. For Chrome Extension sessions, use one final:

browser.tabs.finalize({ keep: [...] })

This workaround is advisory and can be defeated by model error; it is not a product fix.

Suggested acceptance tests

  • Claimed external tab + direct close: rejected without explicit close intent.
  • Unknown or restored provenance + direct close: rejected.
  • Current-session agent-created tab + ordinary cleanup: closes.
  • Claimed user tab omitted from finalization: released and remains open.
  • Explicit owner command targeting one tab or a frozen bounded set: supported through an explicit authorized route.
  • No regression to handoff or deliverable tabs.

Requested product boundary

Please enforce tab provenance and cleanup ownership in the close path itself. The exact internal mechanism for propagating explicit owner close intent is an implementation choice; this report only asks that a claimed user tab cannot be closed through the generic direct-close route without that authorization.

View original on GitHub ↗