From b960cfd2a1fb8e9542c5d2904a574a92625e9fa0 Mon Sep 17 00:00:00 2001 From: Matti Nannt Date: Tue, 6 Jan 2026 07:21:19 +0100 Subject: [PATCH] chore: harden CSP and X-Frame-Options headers (#7062) Co-authored-by: pandeymangg --- apps/web/next.config.mjs | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/apps/web/next.config.mjs b/apps/web/next.config.mjs index 090208accd..65dccdce2e 100644 --- a/apps/web/next.config.mjs +++ b/apps/web/next.config.mjs @@ -133,15 +133,32 @@ const nextConfig = { const isProduction = process.env.NODE_ENV === "production"; const scriptSrcUnsafeEval = isProduction ? "" : " 'unsafe-eval'"; + const cspBase = `default-src 'self'; script-src 'self' 'unsafe-inline'${scriptSrcUnsafeEval} https:; style-src 'self' 'unsafe-inline' https:; img-src 'self' blob: data: http://localhost:9000 https:; font-src 'self' data: https:; connect-src 'self' http://localhost:9000 https: wss:; frame-src 'self' https://app.cal.com https:; media-src 'self' https:; object-src 'self' data: https:; base-uri 'self'; form-action 'self'`; + return [ { - // Apply X-Frame-Options to all routes except those starting with /s/ or /c/ + // Apply X-Frame-Options and restricted frame-ancestors to all routes except those starting with /s/ or /c/ source: "/((?!s/|c/).*)", headers: [ { key: "X-Frame-Options", value: "SAMEORIGIN", }, + { + key: "Content-Security-Policy", + value: `${cspBase}; frame-ancestors 'self'`, + }, + ], + }, + { + // Allow surveys (/s/*) and contact survey links (/c/*) to be embedded in iframes on any domain + // Note: These routes need frame-ancestors * to support embedding surveys in customer websites + source: "/(s|c)/:path*", + headers: [ + { + key: "Content-Security-Policy", + value: `${cspBase}; frame-ancestors *`, + }, ], }, { @@ -179,10 +196,6 @@ const nextConfig = { key: "X-Content-Type-Options", value: "nosniff", }, - { - key: "Content-Security-Policy", - value: `default-src 'self'; script-src 'self' 'unsafe-inline'${scriptSrcUnsafeEval} https:; style-src 'self' 'unsafe-inline' https:; img-src 'self' blob: data: http://localhost:9000 https:; font-src 'self' data: https:; connect-src 'self' http://localhost:9000 https: wss:; frame-src 'self' https://app.cal.com https:; media-src 'self' https:; object-src 'self' data: https:; base-uri 'self'; form-action 'self'`, - }, { key: "Strict-Transport-Security", value: "max-age=63072000; includeSubDomains; preload",