From 3f6f845c02ed3ace57102f61cbd1c0278d2f4fbb Mon Sep 17 00:00:00 2001 From: Matt Date: Thu, 25 Jun 2026 14:26:38 +0200 Subject: [PATCH] fix(csp): add frame-src so signed-PDF previews + embedded signing load MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The CSP set default-src 'self' with no frame-src, so it fell back to 'self' for frames. Inline signed-EOI previews iframe a presigned s3.portnimara.com URL and the admin embedded-signing card iframes the Documenso host — both were blocked, rendering a broken-file placeholder ("Framing 'https://s3.portnimara.com/' violates ... default-src 'self'"). Add `frame-src 'self' blob: https:` to both CSP definitions (proxy.ts middleware + next.config.ts), matching the existing https: posture of img-src/connect-src. frame-ancestors 'none' is unchanged, so we still can't be embedded by third parties. Co-Authored-By: Claude Opus 4.8 (1M context) --- next.config.ts | 4 ++++ src/proxy.ts | 6 ++++++ 2 files changed, 10 insertions(+) diff --git a/next.config.ts b/next.config.ts index 00952488..7f85c105 100644 --- a/next.config.ts +++ b/next.config.ts @@ -53,6 +53,10 @@ const csp = [ "img-src 'self' data: blob: https:", "font-src 'self' data:", `connect-src 'self' ws: wss: https:${devConnectHosts}`, + // PDF previews iframe a presigned storage URL; embedded-signing iframes the + // Documenso host. Both are per-port/per-env, so allow https: (matching + // img-src). frame-ancestors 'none' still blocks others from embedding us. + "frame-src 'self' blob: https:", "frame-ancestors 'none'", "base-uri 'self'", "form-action 'self'", diff --git a/src/proxy.ts b/src/proxy.ts index c141d567..4886aed1 100644 --- a/src/proxy.ts +++ b/src/proxy.ts @@ -29,6 +29,12 @@ function buildCspWithNonce(nonce: string, isProd: boolean): string { "img-src 'self' data: blob: https:", "font-src 'self' data:", connectSrc, + // PDF previews (signed EOIs etc.) iframe a presigned storage URL, and the + // embedded-signing card iframes the Documenso host. Both are per-port / + // per-env hosts, so allow https: (matching img-src/connect-src). This is + // what WE may embed; frame-ancestors 'none' below still blocks others + // from embedding us. + "frame-src 'self' blob: https:", "frame-ancestors 'none'", "base-uri 'self'", "form-action 'self'",