diff --git a/apps/server/src/http.test.ts b/apps/server/src/http.test.ts index ef75d9446158..4f6b6e3d2535 100644 --- a/apps/server/src/http.test.ts +++ b/apps/server/src/http.test.ts @@ -382,14 +382,16 @@ describe("assetResponseHeaders", () => { assetResponseHeaders("/attachments/upload.bin", { mimeType: "text/html" }), ).toMatchObject({ "Content-Type": "text/html; charset=utf-8", - "Content-Security-Policy": "sandbox allow-scripts allow-forms allow-popups allow-modals", + "Content-Security-Policy": + "sandbox allow-scripts allow-forms allow-popups allow-modals allow-downloads", }); }); it("serves HTML assets as utf-8 inside a sandboxed origin", () => { for (const path of ["/workspace/page.html", "/workspace/PAGE.HTM", "/tmp/report.html"]) { expect(assetResponseHeaders(path)).toMatchObject({ "Content-Type": "text/html; charset=utf-8", - "Content-Security-Policy": "sandbox allow-scripts allow-forms allow-popups allow-modals", + "Content-Security-Policy": + "sandbox allow-scripts allow-forms allow-popups allow-modals allow-downloads", }); } }); diff --git a/apps/server/src/http.ts b/apps/server/src/http.ts index 30b368e62167..7d839e7cae89 100644 --- a/apps/server/src/http.ts +++ b/apps/server/src/http.ts @@ -55,7 +55,9 @@ const SVG_CONTENT_SECURITY_POLICY = "default-src 'none'; style-src 'unsafe-inlin // HTML previews are agent output, not the app. The sandbox gives the document an // opaque origin: scripts run, but same-origin cookies, storage, and API calls are // out of reach. Relative sibling assets still load through their signed URLs. -const HTML_CONTENT_SECURITY_POLICY = "sandbox allow-scripts allow-forms allow-popups allow-modals"; +// Downloads stay allowed, so a page's own download button can save a file. +const HTML_CONTENT_SECURITY_POLICY = + "sandbox allow-scripts allow-forms allow-popups allow-modals allow-downloads"; // Types a browser may render as a document if a proxy strips the disposition // header. Downloads of these fall back to octet-stream. diff --git a/apps/web/src/components/files/BrowserDocumentFrame.tsx b/apps/web/src/components/files/BrowserDocumentFrame.tsx index 0be9c724ca00..cc4b1796a936 100644 --- a/apps/web/src/components/files/BrowserDocumentFrame.tsx +++ b/apps/web/src/components/files/BrowserDocumentFrame.tsx @@ -34,7 +34,7 @@ export function BrowserDocumentFrame(props: { src={props.src} title={props.title} className={className} - sandbox="allow-scripts allow-forms allow-popups allow-modals" + sandbox="allow-scripts allow-forms allow-popups allow-modals allow-downloads" /> ); }