Studio: block tabnabbing from HTML preview popups
Codex P1 on the previous commit: granting both ``allow-popups`` and ``allow-popups-to-escape-sandbox`` while forcing every link through ``<base target="_blank">`` lets a malicious assistant-emitted link open a regular browser tab that retains ``window.opener``. The destination page can then call ``window.opener.top.location.href = '...'`` and tabnab the original Studio tab. Drop ``allow-popups-to-escape-sandbox``. ``allow-popups`` stays so the click still produces a tab instead of being silently dropped, but the popup now INHERITS the iframe sandbox (no allow-same-origin, no allow-top-navigation), so it cannot reach back into the host. Trade-off: the opened tab loads with an opaque origin and some real sites render degraded inside the popup. This is the deliberate exchange for tabnabbing safety; the chat-message preview iframe is the primary surface, the popup is a follow-up link click. Existing rendering-iframe sandbox test now asserts allow-popups-to-escape-sandbox is NOT present.
This commit is contained in:
parent
115ff8978c
commit
e3c7948874
2 changed files with 20 additions and 13 deletions
|
|
@ -26,17 +26,19 @@ describe("HtmlSvgRenderer", () => {
|
|||
) as HTMLIFrameElement;
|
||||
expect(iframe.tagName).toBe("IFRAME");
|
||||
// SECURITY: allow-scripts + allow-modals leave script / alert /
|
||||
// confirm operative IF the inherited host CSP ever permits inline;
|
||||
// allow-popups + allow-popups-to-escape-sandbox so a `<base
|
||||
// target="_blank">` link does not silently no-op; NEVER
|
||||
// allow-same-origin or allow-top-navigation -- those would let
|
||||
// the preview read parent.document and exfiltrate session data.
|
||||
// confirm operative if the inherited host CSP ever permits inline.
|
||||
// allow-popups lets ``<base target="_blank">`` links open without
|
||||
// being silently dropped, BUT the popups INHERIT the sandbox
|
||||
// (allow-popups-to-escape-sandbox is intentionally absent) so a
|
||||
// tab opened from a malicious assistant link cannot use
|
||||
// window.opener.top.location.* to tabnab the Studio tab.
|
||||
// allow-same-origin and allow-top-navigation are NEVER granted.
|
||||
const sandbox = iframe.getAttribute("sandbox") ?? "";
|
||||
const sandboxTokens = sandbox.split(/\s+/);
|
||||
expect(sandboxTokens).toContain("allow-scripts");
|
||||
expect(sandboxTokens).toContain("allow-modals");
|
||||
expect(sandboxTokens).toContain("allow-popups");
|
||||
expect(sandboxTokens).toContain("allow-popups-to-escape-sandbox");
|
||||
expect(sandboxTokens).not.toContain("allow-popups-to-escape-sandbox");
|
||||
expect(sandbox).not.toContain("allow-same-origin");
|
||||
expect(sandbox).not.toContain("allow-top-navigation");
|
||||
// srcdoc carries the assistant HTML plus a defense-in-depth meta
|
||||
|
|
|
|||
|
|
@ -356,13 +356,18 @@ function HtmlPreview({
|
|||
// that includes 'unsafe-inline'
|
||||
// allow-modals -- alert/confirm/prompt are not no-ops
|
||||
// when scripts do fire
|
||||
// allow-popups + -- a ``<base target="_blank">`` link
|
||||
// allow-popups-to- opens a regular browser tab rather
|
||||
// escape-sandbox than an opaque-origin sandboxed one
|
||||
// We do NOT grant allow-same-origin or allow-top-navigation, so
|
||||
// the iframe cannot read parent.document, navigate the host
|
||||
// page, or escape its origin.
|
||||
sandbox="allow-scripts allow-modals allow-popups allow-popups-to-escape-sandbox"
|
||||
// allow-popups -- the ``<base target="_blank">`` link
|
||||
// rule can open a new tab instead of
|
||||
// silently dropping the click
|
||||
// We do NOT grant:
|
||||
// allow-same-origin / allow-top-navigation -- the iframe
|
||||
// cannot read parent.document or navigate the host page
|
||||
// allow-popups-to-escape-sandbox -- popups INHERIT the sandbox
|
||||
// so an opened tab cannot use ``window.opener.top.location``
|
||||
// to tabnab the Studio tab. The opened tab loads with an
|
||||
// opaque origin (some sites will render degraded) which is
|
||||
// the deliberate trade-off for tabnabbing safety.
|
||||
sandbox="allow-scripts allow-modals allow-popups"
|
||||
style={{
|
||||
width: "100%",
|
||||
height: iframeHeight,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue