diff --git a/studio/frontend/src/components/assistant-ui/__tests__/html-svg-renderer.test.tsx b/studio/frontend/src/components/assistant-ui/__tests__/html-svg-renderer.test.tsx
index 4de79e7b7c..6cbb635d1b 100644
--- a/studio/frontend/src/components/assistant-ui/__tests__/html-svg-renderer.test.tsx
+++ b/studio/frontend/src/components/assistant-ui/__tests__/html-svg-renderer.test.tsx
@@ -27,10 +27,16 @@ describe("HtmlSvgRenderer", () => {
expect(iframe.tagName).toBe("IFRAME");
// SECURITY: allow-scripts + allow-modals leave script / alert /
// confirm operative IF the inherited host CSP ever permits inline;
- // NEVER allow-same-origin or allow-top-navigation -- those would let
+ // allow-popups + allow-popups-to-escape-sandbox so a `` 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.
const sandbox = iframe.getAttribute("sandbox") ?? "";
- expect(sandbox.split(/\s+/)).toContain("allow-scripts");
+ 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(sandbox).not.toContain("allow-same-origin");
expect(sandbox).not.toContain("allow-top-navigation");
// srcdoc carries the assistant HTML plus a defense-in-depth meta CSP
diff --git a/studio/frontend/src/components/assistant-ui/html-svg-renderer.tsx b/studio/frontend/src/components/assistant-ui/html-svg-renderer.tsx
index 8664e0469f..612f258916 100644
--- a/studio/frontend/src/components/assistant-ui/html-svg-renderer.tsx
+++ b/studio/frontend/src/components/assistant-ui/html-svg-renderer.tsx
@@ -346,12 +346,23 @@ function HtmlPreview({
data-testid="html-svg-renderer-iframe"
title="HTML preview"
srcDoc={srcDoc}
- // SECURITY: allow-scripts (in case the host CSP ever loosens to
- // permit inline) + allow-modals (so alert/confirm do not silently
- // no-op when scripts do run). 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"
+ // SECURITY:
+ // allow-scripts -- in case the host CSP ever loosens
+ // to permit inline (today it does not)
+ // allow-modals -- so alert/confirm/prompt do not no-op
+ // when scripts do run
+ // allow-popups + -- so the ```` we
+ // allow-popups-to- set above can open a new tab without
+ // escape-sandbox being silently dropped; escape-
+ // sandbox makes the popup a regular
+ // browser tab rather than an opaque-
+ // origin sandboxed one (the popup is
+ // equivalent to the user clicking the
+ // same URL in any other web app)
+ // 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"
style={{
width: "100%",
height: iframeHeight,