Repository navigation
Enforce secure nested-document lifecycle for Code OSS webviews #267
Description
Activity
- addedvscode-oss/plannedPlanned for the AppScene/WebScene VS Code OSS integrationPlanned for the AppScene/WebScene VS Code OSS integration
on Sep 17, 2026 Added native child #399 for the first reproduced unchanged-Code blocker after #392: preserve the same-origin iframe WindowProxy and pre-navigation DOMContentLoaded subscription through
fake.htmlnavigation, then allow the navigated Document'sopen/write/closereplacement. Chrome 153 passes the focused sequence; exact main93780758times out before the lifecycle callback. Scope excludes #393 CSS paths and all cross-origin/CSP/admission/traversal expansion.#399 is complete via #402, merged at
51f71381bda9015b64cf0566534e209f8bfa9986.The unchanged Code OSS Markdown iframe bootstrap now keeps a stable same-origin
WindowProxyacross navigation anddocument.open/write/close, delivers the navigated document lifecycle, and cleans retained listeners across 100 teardown cycles. Chrome 153 passed 6/6; the focused native gate passed with p95 3.176 ms, flat measured heap (1,359,228 bytes), and bounded RSS (40.9 -> 89.9 MiB). Opaque/cross-origin frames remain fail-closed. Linux, macOS, portable V8, native-document, and NativeAOT 11/12 checks passed on exact PR head400316f638e4e031cab2378722c421863d9a6032; unrelated NuGet packaging was canceled.Current-main audit after the implementation-only #268 slices: #267 remains open and unchanged at cumulative main
4ea2feebd0dd7f2f08dfa1a8bfbbe1ca5f3d6c3b.The merged Select All and command-capability work does not widen iframe origin, sandbox, CSP, Permissions Policy, navigation, or resource admission. Remaining #267 implementation still includes CSP nonce/source enforcement for Markdown, Permissions Policy, broader same-origin/opaque/cross-origin navigation behavior, reload/error/beforeunload/pagehide ordering, stale-generation rejection, and repeated replacement/detach teardown. Its required WPT/Chromium/native/security/performance and exact unchanged-product evidence remains outstanding.
#448 is complete via #450, merged as
aa276b17c42eee22dd067f6872afc4b2d02f4034from the current-main baselinea263f4e.The reusable nested-document policy path now reflects
HTMLIFrameElement.allowand enforces inherited iframe Permissions Policy admission for the two unchanged VS Code OSS clipboard features,clipboard-readandclipboard-write. The parser covers default same-origin behavior, bare/source-origin delegation,self,src,*,none, and explicit origins. Denied calls reject withNotAllowedErrorbefore native host handoff; existing user-activation, MIME, quota, and host-request checks remain in force.This closes the smallest proven Permissions Policy gap used by
webviewElement.tsandbrowser/pre/index.html. CSP enforcement, response-header policy, other policy-controlled features, cross-origin WindowProxy work, and the broader navigation/teardown matrix remain open in #267.Validation debt is deliberate under the implementation-only directive: no focused tests, benchmarks, broad native build, package qualification, or CI wait was run. The generated WebIDL binding was regenerated and
git diff --checkpassed after rebasing; cumulative validation remains assigned to #264/#267.#454 is complete via #455, merged as
a2f873e822fd83af9a41013989aabbf94b520bf3after rebasing onto current main580f177c18b067bd6b11aef9d7b2b2e400804a0d.Nested iframe hydration now reads the first effective meta Content Security Policy in parser order and applies
script-src-elem,script-src, ordefault-srcfallback before speculative fetch and evaluation. This preserves the prelude-injected API script that precedes the meta policy, admits unchanged Markdown's nonce-bearing scripts, handles boundedunsafe-inline,self, scheme, explicit-origin, and wildcard-host sources, and reflects the active script nonce.The focused boundary does not claim response-header CSP, style/image/font/media/connect/frame/worker directives, violation events/reporting, hash sources, dynamic insertion, or multiple-policy intersection; those remain in #267.
Validation debt is deliberate under the implementation-only directive: no focused tests, benchmarks, broad native build, package qualification, or CI wait was run.
git diff --checkpassed before the required rebase; cumulative security and unchanged-product validation remains assigned to #264/#267.#460 is complete via #461, merged as
c19fbc36ddd36d23eb9116b354295acf05ee9e58after rebasing onto current main1d663aeb825fd12ac1f9c3822a65a4c53fd07b1f.Each authored iframe
srcnavigation anddocument.open()replacement now advances a per-frame generation. Navigation clears stale response bytes, retires an earlier preparation future without blocking the new one, deduplicates queued hydration, and binds async preparation plus cooperative script/DOMContentLoaded/load continuation to the captured generation. Detach and top-level teardown retire the generation state. This closes the same-URL/source-race path where older work was previously identified only by frame ID and source text.Full
location.reload(), history traversal, beforeunload/pagehide, cross-origin WindowProxy behavior, error-event ordering, and performance qualification remain in #267.Validation debt is deliberate under the implementation-only directive: no focused tests, benchmarks, broad native build, package qualification, or CI wait was run.
git diff --checkpassed before the required rebase; cumulative lifecycle and unchanged-product validation remains assigned to #264/#267.#466 is complete via #467, merged as
6363114a6b75c6d5905adabd491820194ed4e174after rebasing onto current mainb383afc181e4794ef7b7f5266cb8f5d51c6c41b1.The outgoing nested Window now receives one non-bubbling, non-cancelable
pagehidewithpersisted === falsebefore navigation generation advances or iframe detach cancels realm tasks. The one-shot guard resets when a replacement realm becomes active and is cleared on teardown. This covers unchanged VS Code'soldActiveFrame.remove()replacement and Markdown Editor'spagehidescroll-state persistence hook.beforeunloadcancellation, visibility transitions, unload, explicit reload/history, cross-origin proxies, and broad event-order validation remain in #267. This is the final implementation slice in the current wave.Validation debt is deliberate under the implementation-only directive: no focused tests, benchmarks, broad native build, package qualification, or CI wait was run.
git diff --checkpassed before the required rebase; cumulative lifecycle and unchanged-product validation remains assigned to #264/#267.- added sub-issues
on Sep 21, 2026
Exact merged-head diagnostic checkpoint — 21 September 2026
Unchanged Code OSS
645f29ccis pinned locally with merged WebScene5b4739c8(native stack #902, focused PRs #899–#901 merged) and merged AppScene36d7a82e(focused PR #403 merged). The demo branch is clean at local commit074d2cbe, unpushed, with Actions disabled. No focused PRs remain open; keep WebScene consolidation #76, AppScene consolidation #65 and vscode-demo integration #1 open/unmerged.A clean 2,909-file SDK from those exact heads passed native CTest, macOS runtime profile, installed CLI verification and release preflight. The CLI published a signed 709 MiB local diagnostic Release at
vscode-demo/dist/appscene-release-36d7a82-5b4739c8-markdown/Code OSS AppScene.app; strict codesign and the installed-resource callback contract pass. Native computer input opened real remotebeta/README.mdand five Explorer rows. A Markdown Preview editor then appeared with a blank white pane; the current trace does not isolate the next nested resource/message failure, and the shortcut sequence also pasted clipboard text into the fixture editor. This is not a qualified full release. AppScene #402/#398 and WebScene #264/#267 stay open.Resume with controlled native Preview invocation and nested resource/worker/message tracing; require actual painted Markdown, Chromium-matched geometry, security, lifecycle and performance. Then continue Explorer first-child paint #252/#243 and AppScene picker #131, remote Save As/recovery #269, terminal #244, CSS #235, accessibility/Chat, Linux/Windows WPT, bundle-size and release-wide CI gates. The authored open-issue inventory and exact local evidence are in
vscode-demo/docs/open-issue-plan.mdanddocs/validation/markdown-preview-prelude-080ee9c-20260921.md. No Electron/CEF shell or Code OSS source rewrite was introduced.Parent epic: #264. Top-level release epic: #227.
Proven gap
After service-worker readiness, unchanged
browser/pre/index.htmlcreates a nested iframe, sets a sandbox and Permissions Policy, navigates it tofake.html, readscontentWindow/contentDocument, then callsdocument.open(),write(), andclose()with extension HTML. Updates replace the active frame. The prelude observes DOMContentLoaded/load/beforeunload, posts messages across the frame, uses ResizeObserver, preserves scroll, and removes stale frames.WebScene's capability record at
b81f594cexplicitly limits iframe support to an initial same-origin document and leaves navigatedsrc/srcdoc, history, sandboxing, origin transitions, cross-origin access control, complete load/error order, repeated-navigation teardown, and arbitrary iframe rendering outside the claim. No CSP enforcement implementation was found in the audited runtime. #253 owns the sandbox DOMTokenList and token semantics; this issue owns the resulting browsing-context, document, origin, CSP, Permissions Policy, navigation, and replacement behavior.Dependencies and boundaries
https://{{uuid}}.vscode-cdn.net/...URL and the outer workbench CSP permitshttps://*.vscode-cdn.netframes. Native acceptance must preserve equivalent origin separation even when packaged transport is not HTTP.Acceptance
src,srcdoc,fake.html, base URL, initialabout:blank, realm/constructor identity,contentWindow/contentDocument,parent/top/frameElement, same-origin access, opaque sandbox origins, cross-origin denial, postMessage target/origin, CSP nonces/sources, permissions, and links/download/navigation admission.open/write/close, update replacement, reload, detach during load, error, beforeunload/pagehide, observer disconnect, and shutdown produce browser-order events and reject callbacks from stale generations.Proposed PR stack