T-01b: Agent pop-out/open-tab reopens the storage boundary (EXECUTED FAIL, no fix on this branch) - #122
Open
Natoshi-moto wants to merge 8 commits into
Open
T-01b: Agent pop-out/open-tab reopens the storage boundary (EXECUTED FAIL, no fix on this branch)#122Natoshi-moto wants to merge 8 commits into
Natoshi-moto wants to merge 8 commits into
Conversation
Carries forward Grok's 2026-07-25 CARD-04 re-run (session 3) and the Fable fix-draft handoff so the evidence this fix responds to travels with the fix itself. status_authority: NONE
The Agent iframe was served from a same-origin relative path AND sandboxed with allow-same-origin, so the sandbox provided no real storage boundary: script inside the iframe could read/write the host's localStorage and open its IndexedDB directly, with no bridge involved. EXECUTED-confirmed twice (BREAK_SESSION_20260722 CARD-04, Anthropic; BREAK_SESSION_20260725 CARD-04, xAI). Fix: remove allow-same-origin so the iframe gets an opaque origin. Verified live that this closes the hole (ODS-SEC-001/002, new permanent regression test at scripts/ods-sec-001-t01-storage-boundary.mjs, npm run ods:sec001). This makes the Agent's own storage calls throw too, so four call sites in nexus-agent-v0.14-scrubbed.html that read/wrote localStorage/sessionStorage without a try/catch are now guarded — matching the storage layer's existing degrade-to-memory design instead of crashing. The runAuthGate() sessionStorage recovery check was the critical one: unguarded, it would have failed auth on every boot, not just recovery attempts. Synced products/nexus-blocks' canonical copy to match (README: noted-host serves a byte-identical mirror); registry verify still passes. Verified: existing agent:prompt-smoke and bridge:smoke both pass with zero console/page errors, typecheck clean, new ods:sec001 passes. python3 -m unittest discover -s tests: 189/190 pass, the 1 failure is pre-existing node_modules symlink/JSON tooling noise unrelated to this change (same class already flagged in BREAK_SESSION_20260725). Scope: T-01 storage boundary only. T-02 (unpinned CDN), T-03 (default proxy), CARD-11 (crypto), and the production/dist second-origin question (CARD-12 dist parity) are untouched and remain open. status_authority: NONE — proposal/fix branch, not merged to main.
Documents the re-probe (ODS-SEC-001/002 now PASS on this branch), what was verified, what was not (dist/ build, long-session behavior), and the residual risks per the original handoff's required structure. status_authority: NONE
Round-close publication + epistemic performance analysis per the mandatory skill, documenting the T-01 fix, what was verified, what was not, and the authorization-mapping inference made from the operator's plain-language instruction. status_authority: NONE
The T-01 fix (d59c15e) is correct and re-verified — `npm run ods:sec001` passes. But it closes one of three routes into the same capability. NexusAgentStudio.tsx opens the same Agent document top-level and unsandboxed at line 46 ("Pop out", window.open) and line 89 ("Open tab", <a target="_blank">) — ~40 lines above the line the fix patched. A top-level same-origin document owns that origin's storage, so clicking "Pop out" on the post-fix tree yields: host_ls_read SUCCEEDED (synthetic canary retrieved verbatim) host_ls_write SUCCEEDED (host page read the value back) host_keys_visible 13 host_idb_open SUCCEEDED (nexus-kernel) noopener/noreferrer do not mitigate this — they sever window.opener, not origin-scoped storage. Filed: - operations/receipts/T01_FIX_20260725/CARD-04B-POPOUT.md (EXECUTED) - products/noted-host/scripts/ods-sec-003-t01b-popout-boundary.mjs (npm run ods:sec003) — checked in KNOWN RED, deliberately, not wired into any aggregate gate - operations/handoffs/T01B_POPOUT_BOUNDARY_ADVERSARIAL_HANDOFF_001.md — tear apart / fix / break / fix brief for the next seat - correction banner on T01_IFRAME_STORAGE_BOUNDARY_FABLE_RESPONSE.md, whose §1 asserted no such route exists - round report + epistemic analysis + INDEX rows No product code changed. Nothing merged; main untouched. Not independent review — same model family as the seat that wrote the fix. status_authority: NONE Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…E_ON_BRANCH) Adds a proposed constitutional continuity loop: assess the prior task, attack the current task, append state without erasing history, and never mistake the resulting record for truth. Operator's verbatim message preserved in both the constitutional document and a filed disclosure. Wires the protocol into AGENTS.md, README_START_HERE.md, the mandatory epistemic skill, and its template. status_authority: NONE — no merge/push authorization claimed by the originating round; pushed here on direct operator instruction. Co-Authored-By: Codex <noreply@openai.com>
Pre-warning filed before the T-01b adversarial review (PR #122) lands: the operator's credits for the reviewing Fable seat ran out partway through, and they switched to Opus to continue. Filed per this repo's disclosure discipline so the eventual review is read knowing it may cross a model-family seam mid-task, not just what it concludes. status_authority: NONE Co-Authored-By: Claude Code <noreply@anthropic.com>
Owner
Author
|
Pre-warning for reviewers (Fable/Opus): the operator's credits for the Fable seat ran out partway through this review and they switched to Opus 5 to continue. Filed as a disclosure so the eventual review is read knowing it may cross a model-family seam mid-task — see |
Extends the T-01b arc. Documents only — no product code touched, no gate lifted. G-01 stays RED. Findings (evidence in EVIDENCE_ORIGIN_MODEL.md, probe checked in, re-runnable): - Nexus_OS.html:1619/:1629 grants allow-same-origin to EVERY block it spawns, so the sandbox attribute is non-load-bearing for all 71 blocks. The Agent was never a special case (SOURCE_TRACED). - The T-01 fix hardened 1 of 4 same-origin iframes. Router, Diagnostics and PromptStudioV3 still carry allow-same-origin; PromptStudioV3 holds the ps3 credential blob (SOURCE_TRACED). - Handoff Option C (blob:/data: delivery) is FALSIFIED: blob: inherits the creator's origin and read the host canary on both engines (EXECUTED). - Two of three stated justifications for allow-same-origin are FALSIFIED: WebCrypto is present under an opaque origin, and cross-origin dynamic import() works. Only the localStorage objection survives (EXECUTED). - Cross-origin tab (second port) is isolated, keeps its own storage, supports NATIVE fullscreen, and carries a verifiable event.origin (EXECUTED). - noopener and a control channel are mutually exclusive; dropping noopener permits tabnabbing (EXECUTED, both engines). Probe integrity: the tabnabbing assertion first reported HOLDS because an escaped </script> meant the payload never ran. A probe that fails to execute reports green. Recorded against my own interest; the corrected result stands. Not executed / open: F-T01B-C (user-opened file -> privileged block) is an inference from two verified links. WebKit untested. Real esm.sh graphs untested (local CORS module only, per the no-third-party-probing rule). Opens AUD-EXT-ORIGIN-MODEL-001: blind-first audit per constitution/AUDIT.md, open to any provider family. All prior analysis in this arc is Anthropic-authored and therefore SAME_FAMILY_DIFFERENTIAL, not independent corroboration. Gates run clean with node_modules parked: doctor 0, verify 0, 190 tests OK. status_authority: NONE Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Status
No product code is proposed for merge here. This PR queues a security finding + evidence for review — the underlying question (remove the buttons? separate origin? disclose?) is an operator decision per the handoff brief.
One line
The T-01 iframe fix is real and verified. T-01 is still open through two other buttons in the Agent's own title bar — "Pop out" and "Open tab" — which load the same document top-level and unsandboxed, so it owns the host's storage outright.
What's in this branch
communications/publications/rounds/NOTED/2026-07-25_claude_t01b-popout-boundary-finding.md— round report (plain-language summary + what was verified)operations/receipts/T01_FIX_20260725/CARD-04B-POPOUT.md— EXECUTED FAIL evidence (live probe: host localStorage read/write bothSUCCEEDEDfrom the popped-out window, IndexedDB opened)communications/publications/epistemic/2026-07-25_claude_t01b-popout-boundary-epistemic.md— epistemic analysisproducts/noted-host/scripts/ods-sec-003-t01b-popout-boundary.mjs(npm run ods:sec003) — permanent regression probe, checked in as a known red so the gap can't be forgottenoperations/handoffs/T01B_POPOUT_BOUNDARY_ADVERSARIAL_HANDOFF_001.md— tear-apart → fix → break → fix brief for whoever picks this up, with explicit kill criteria (any fix touching auth/crypto/deployment stops and returns to the operator)Non-claims
status_authority: NONEdist/build unprobed; T-02, T-03, CARD-11 untouched🤖 Generated with Claude Code