From f63c5785044be8305c7ee521f1640f6723fe1a1e Mon Sep 17 00:00:00 2001 From: Alexander Tarasov Date: Mon, 26 Feb 2024 12:48:09 +0100 Subject: [PATCH] conditional CSP depending on path --- src/middleware.ts | 48 ++++++++++++++++++++++++++++++++++------------- 1 file changed, 35 insertions(+), 13 deletions(-) diff --git a/src/middleware.ts b/src/middleware.ts index 1617a4678b9b4..2ce059a86f6ed 100644 --- a/src/middleware.ts +++ b/src/middleware.ts @@ -1,24 +1,41 @@ import {NextRequest, NextResponse} from 'next/server'; export function middleware(request: NextRequest) { - const nonce = Buffer.from(crypto.randomUUID()).toString('base64'); - const cspHeader = ` + let cspHeader = ` + upgrade-insecure-requests; default-src 'none'; - base-uri 'none'; - script-src 'self' 'unsafe-inline' 'nonce-${nonce}' 'strict-dynamic'; - connect-src 'self' o1.ingest.sentry.io plausible.io; + script-src 'self' 'unsafe-inline' 'unsafe-eval' *.sentry-cdn.com www.googletagmanager.com plausible.io vercel.live; + connect-src 'self' *.sentry.io sentry.io *.algolia.net *.algolianet.com *.algolia.io plausible.io reload.getsentry.net storage.googleapis.com; + img-src * 'self' data: www.google.com www.googletagmanager.com; style-src 'self' 'unsafe-inline'; - img-src 'self' docs.sentry.io storage.googleapis.com; - font-src 'self'; + font-src 'self' fonts.gstatic.com; + frame-src demo.arcade.software player.vimeo.com; worker-src blob:; - upgrade-insecure-requests; -`; - // Replace newline characters and spaces - const contentSecurityPolicyHeaderValue = cspHeader.replace(/\s{2,}/g, ' ').trim(); + report-uri https://o1.ingest.sentry.io/api/1267915/security/?sentry_key=ad63ba38287245f2803dc220be959636 + `; const requestHeaders = new Headers(request.headers); - requestHeaders.set('x-nonce', nonce); + const url = new URL(request.url); + if (url.pathname.startsWith('/changelog/')) { + const nonce = Buffer.from(crypto.randomUUID()).toString('base64'); + cspHeader = ` + default-src 'none'; + base-uri 'none'; + script-src 'self' 'unsafe-inline' 'nonce-${nonce}' 'strict-dynamic'; + connect-src 'self' o1.ingest.sentry.io plausible.io; + style-src 'self' 'unsafe-inline'; + img-src 'self' docs.sentry.io storage.googleapis.com; + font-src 'self'; + worker-src blob:; + upgrade-insecure-requests; + `; + + requestHeaders.set('x-nonce', nonce); + } + + // Replace newline characters and spaces + const contentSecurityPolicyHeaderValue = cspHeader.replace(/\s{2,}/g, ' ').trim(); requestHeaders.set('Content-Security-Policy', contentSecurityPolicyHeaderValue); const response = NextResponse.next({ @@ -26,7 +43,12 @@ export function middleware(request: NextRequest) { headers: requestHeaders, }, }); - response.headers.set('Content-Security-Policy', contentSecurityPolicyHeaderValue); + + let cspHeaderName = 'Content-Security-Policy-Report-Only'; + if (process.env.IS_PRODUCTION === 'true') { + cspHeaderName = 'Content-Security-Policy'; + } + response.headers.set(cspHeaderName, contentSecurityPolicyHeaderValue); return response; }