From 78a476f88ede7be00c45ac8e47ac041199282987 Mon Sep 17 00:00:00 2001 From: Max Ammann Date: Wed, 6 Aug 2025 15:00:34 +0200 Subject: [PATCH 01/18] add CSP --- index.html | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/index.html b/index.html index 59866cb0f96..326fa78435e 100644 --- a/index.html +++ b/index.html @@ -2,9 +2,21 @@ - + From 754f01317368b5c857d0ddc8815113a991508198 Mon Sep 17 00:00:00 2001 From: Max Ammann Date: Wed, 6 Aug 2025 16:22:46 +0200 Subject: [PATCH 02/18] fix websocket edge case --- index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.html b/index.html index 326fa78435e..cc5fa9bbdd8 100644 --- a/index.html +++ b/index.html @@ -15,7 +15,7 @@ style-src 'self' 'unsafe-inline'; img-src * 'unsafe-inline'; script-src 'self' https://plausible.corp.zoo.dev/js/script.tagged-events.js 'wasm-unsafe-eval'; - connect-src 'self' https://api.zoo.dev https://api.dev.zoo.dev; + connect-src 'self' https://api.zoo.dev wss://api.zoo.dev https://api.dev.zoo.dev wss://api.dev.zoo.dev; "> From cba168ee9b8f97ea6e807e8a6abe4eb70bbb6af0 Mon Sep 17 00:00:00 2001 From: Max Ammann Date: Thu, 7 Aug 2025 12:03:12 +0200 Subject: [PATCH 03/18] update --- index.html | 2 ++ 1 file changed, 2 insertions(+) diff --git a/index.html b/index.html index cc5fa9bbdd8..36f56300673 100644 --- a/index.html +++ b/index.html @@ -16,6 +16,8 @@ img-src * 'unsafe-inline'; script-src 'self' https://plausible.corp.zoo.dev/js/script.tagged-events.js 'wasm-unsafe-eval'; connect-src 'self' https://api.zoo.dev wss://api.zoo.dev https://api.dev.zoo.dev wss://api.dev.zoo.dev; + object-src 'none'; + frame-ancestors 'none' "> From c3140f4bb6b044ae60dbd8d075c6e53a2192de3b Mon Sep 17 00:00:00 2001 From: Max Ammann Date: Thu, 7 Aug 2025 16:17:38 +0200 Subject: [PATCH 04/18] add plausible connect --- index.html | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/index.html b/index.html index 36f56300673..83592b6ad21 100644 --- a/index.html +++ b/index.html @@ -9,13 +9,16 @@ 3. Allow images from any source and inline images. We fetch user profile images from any origin. 4. Allow scripts from the same origin and from Plausible Analytics. Allow WASM execution. 5. Allow WebSocket connections and fetches to our API. + + We have to use the tag because the Electron app is hosted over file:// and does not support HTTP headers. + Reporting functionality is not supported with tags so we have to get this right. --> From 95187e280dfda6266cfe1f82efbfe1fc42cf4433 Mon Sep 17 00:00:00 2001 From: Max Ammann Date: Tue, 12 Aug 2025 13:14:25 +0200 Subject: [PATCH 05/18] use vite to conditionally change CSP --- index.html | 17 ++------------ src/main.ts | 1 + vercel.json | 8 +++++++ vite.base.config.ts | 52 +++++++++++++++++++++++++++++++++++++++++ vite.config.ts | 4 ++++ vite.renderer.config.ts | 3 ++- 6 files changed, 69 insertions(+), 16 deletions(-) diff --git a/index.html b/index.html index 83592b6ad21..60ae8a1781b 100644 --- a/index.html +++ b/index.html @@ -2,26 +2,13 @@ - - + diff --git a/src/main.ts b/src/main.ts index 57429be9112..2ae18439556 100644 --- a/src/main.ts +++ b/src/main.ts @@ -293,6 +293,7 @@ app.on('window-all-closed', () => { app.on('ready', (event, data) => { // Avoid potentially 2 ready fires if (mainWindow) return + // Create the mainWindow mainWindow = createWindow() // Set menu application to null to avoid default electron menu diff --git a/vercel.json b/vercel.json index b77340e0622..2fbad4b05f6 100644 --- a/vercel.json +++ b/vercel.json @@ -13,6 +13,14 @@ { "key": "X-Robots-Tag", "value": "noindex" + }, + { + "key": "Reporting-Endpoints", + "value": "csp-reporting-endpoint=\"https://csp-logger.vercel.app/csp-report\"" + }, + { + "key": "Content-Security-Policy-Report-Only", + "value": "default-src 'self'; style-src 'self' 'unsafe-inline'; img-src * 'unsafe-inline'; script-src 'self' https://plausible.corp.zoo.dev/js/script.tagged-events.js 'wasm-unsafe-eval'; connect-src 'self' https://api.zoo.dev wss://api.zoo.dev https://api.dev.zoo.dev wss://api.dev.zoo.dev; object-src 'none'; frame-ancestors 'none'; report-uri https://csp-logger.vercel.app/csp-report; report-to csp-reporting-endpoint" } ] } diff --git a/vite.base.config.ts b/vite.base.config.ts index 515e959eefa..182eec1acba 100644 --- a/vite.base.config.ts +++ b/vite.base.config.ts @@ -115,3 +115,55 @@ export function pluginHotRestart(command: 'reload' | 'restart'): Plugin { }, } } + +export function csp(disable?: boolean): Plugin { + /* + 1. By default, only allow scripts from the same origin. + 2. Allow inline styles and styles from the same origin. This is how we use CSS rightnow. + 3. Allow images from any source and inline images. We fetch user profile images from any origin. + 4. Allow scripts from the same origin and from Plausible Analytics. Allow WASM execution. + 5. Allow WebSocket connections and fetches to our API. + */ + let csp = ` + default-src 'self'; + style-src 'self' 'unsafe-inline'; + img-src * 'unsafe-inline'; + script-src 'self' https://plausible.corp.zoo.dev/js/script.tagged-events.js 'wasm-unsafe-eval'; + connect-src 'self' https://plausible.corp.zoo.dev https://api.zoo.dev wss://api.zoo.dev https://api.dev.zoo.dev wss://api.dev.zoo.dev; + object-src 'none'; + frame-ancestors 'none' + ` + + /* + + 'Reporting-Endpoints': + 'csp-reporting-endpoint="https://csp-logger.vercel.app/csp-report"', + 'Content-Security-Policy-Report-Only': + "default-src 'self'; " + + "style-src 'self' 'unsafe-inline'; " + + "img-src * 'unsafe-inline'; " + + "script-src 'self' https://plausible.corp.zoo.dev/js/script.tagged-events.js 'wasm-unsafe-eval'; " + + "connect-src 'self' https://api.zoo.dev wss://api.zoo.dev https://api.dev.zoo.dev wss://api.dev.zoo.dev; " + + "object-src 'none'; " + + "frame-ancestors 'none'; " + + 'report-uri https://csp-logger.vercel.app/csp-report;' + + 'report-to csp-reporting-endpoint', + + */ + + return { + name: 'html-transform', + transformIndexHtml(html: string) { + let indexHtmlRegex = + // + if (disable) { + return html.replace(indexHtmlRegex, '') + } else { + return html.replace( + indexHtmlRegex, + `` + ) + } + }, + } +} diff --git a/vite.config.ts b/vite.config.ts index 2f8435a4538..5d579ec8b6f 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -7,6 +7,7 @@ import version from 'vite-plugin-package-version' import topLevelAwait from 'vite-plugin-top-level-await' import viteTsconfigPaths from 'vite-tsconfig-paths' import { configDefaults, defineConfig } from 'vitest/config' +import { csp } from './vite.base.config' export default defineConfig(({ command, mode }) => { const runMillion = process.env.RUN_MILLION @@ -77,6 +78,9 @@ export default defineConfig(({ command, mode }) => { }, plugins: [ react(), + // Web deployments that are deployed to production don't need a CSP in the indexHTML. + // They get it through vercel.json. + csp(mode == 'production'), viteTsconfigPaths(), eslint(), version(), diff --git a/vite.renderer.config.ts b/vite.renderer.config.ts index 4cad918fe38..dc07afb5ee0 100644 --- a/vite.renderer.config.ts +++ b/vite.renderer.config.ts @@ -5,7 +5,7 @@ import { defineConfig } from 'vite' import topLevelAwait from 'vite-plugin-top-level-await' import viteTsconfigPaths from 'vite-tsconfig-paths' -import { pluginExposeRenderer } from './vite.base.config' +import { pluginExposeRenderer, csp } from './vite.base.config' // https://vitejs.dev/config export default defineConfig((env) => { @@ -23,6 +23,7 @@ export default defineConfig((env) => { // Needed for electron-forge (in npm run tron:start) optimizeDeps: { esbuildOptions: { target: 'es2022' } }, plugins: [ + csp(), pluginExposeRenderer(name), viteTsconfigPaths(), lezer(), From e71f3d5b6c564353b044000566c99bc8afa689ea Mon Sep 17 00:00:00 2001 From: Max Ammann Date: Tue, 12 Aug 2025 15:15:13 +0200 Subject: [PATCH 06/18] fix vercel config --- vercel.json | 23 ++++++++++++++--------- vite.config.ts | 3 +++ 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/vercel.json b/vercel.json index 2fbad4b05f6..17f50457d32 100644 --- a/vercel.json +++ b/vercel.json @@ -2,7 +2,20 @@ "version": 2, "headers": [ { - "source": "/", + "source": "/(.*)", + "headers": [ + { + "key": "Reporting-Endpoints", + "value": "csp-reporting-endpoint=\"https://csp-logger.vercel.app/csp-report\"" + }, + { + "key": "Content-Security-Policy-Report-Only", + "value": "default-src 'self'; style-src 'self' 'unsafe-inline'; img-src * 'unsafe-inline'; script-src 'self' https://plausible.corp.zoo.dev/js/script.tagged-events.js 'wasm-unsafe-eval'; connect-src 'self' https://api.zoo.dev wss://api.zoo.dev https://api.dev.zoo.dev wss://api.dev.zoo.dev; object-src 'none'; frame-ancestors 'none'; report-uri https://csp-logger.vercel.app/csp-report; report-to csp-reporting-endpoint" + } + ] + }, + { + "source": "/(.*)", "missing": [ { "type": "host", @@ -13,14 +26,6 @@ { "key": "X-Robots-Tag", "value": "noindex" - }, - { - "key": "Reporting-Endpoints", - "value": "csp-reporting-endpoint=\"https://csp-logger.vercel.app/csp-report\"" - }, - { - "key": "Content-Security-Policy-Report-Only", - "value": "default-src 'self'; style-src 'self' 'unsafe-inline'; img-src * 'unsafe-inline'; script-src 'self' https://plausible.corp.zoo.dev/js/script.tagged-events.js 'wasm-unsafe-eval'; connect-src 'self' https://api.zoo.dev wss://api.zoo.dev https://api.dev.zoo.dev wss://api.dev.zoo.dev; object-src 'none'; frame-ancestors 'none'; report-uri https://csp-logger.vercel.app/csp-report; report-to csp-reporting-endpoint" } ] } diff --git a/vite.config.ts b/vite.config.ts index 5d579ec8b6f..eb43df96a51 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -12,6 +12,9 @@ import { csp } from './vite.base.config' export default defineConfig(({ command, mode }) => { const runMillion = process.env.RUN_MILLION + console.error(mode) + console.error("XXXXXXXXX") + return { server: { open: true, From 0b1f9ecf1dcb62b2c55e9349e95b8757d88cb265 Mon Sep 17 00:00:00 2001 From: Max Ammann Date: Tue, 12 Aug 2025 15:15:49 +0200 Subject: [PATCH 07/18] fix --- vite.config.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/vite.config.ts b/vite.config.ts index eb43df96a51..f3ba20826e7 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -12,8 +12,7 @@ import { csp } from './vite.base.config' export default defineConfig(({ command, mode }) => { const runMillion = process.env.RUN_MILLION - console.error(mode) - console.error("XXXXXXXXX") + console.log(`Vite running in ${mode} mode.`) return { server: { From 432f1edd2c2b9212429df09246ba69e9cbf07983 Mon Sep 17 00:00:00 2001 From: Max Ammann Date: Tue, 12 Aug 2025 19:28:34 +0200 Subject: [PATCH 08/18] update CSP --- vercel.json | 2 +- vite.base.config.ts | 78 +++++++++++++++++++++++------------------ vite.config.ts | 15 ++++---- vite.renderer.config.ts | 4 +-- 4 files changed, 55 insertions(+), 44 deletions(-) diff --git a/vercel.json b/vercel.json index 17f50457d32..1e59e5aa5a8 100644 --- a/vercel.json +++ b/vercel.json @@ -10,7 +10,7 @@ }, { "key": "Content-Security-Policy-Report-Only", - "value": "default-src 'self'; style-src 'self' 'unsafe-inline'; img-src * 'unsafe-inline'; script-src 'self' https://plausible.corp.zoo.dev/js/script.tagged-events.js 'wasm-unsafe-eval'; connect-src 'self' https://api.zoo.dev wss://api.zoo.dev https://api.dev.zoo.dev wss://api.dev.zoo.dev; object-src 'none'; frame-ancestors 'none'; report-uri https://csp-logger.vercel.app/csp-report; report-to csp-reporting-endpoint" + "value": "default-src 'self';style-src 'self' 'unsafe-inline';img-src * blob: 'unsafe-inline';script-src 'self' 'wasm-unsafe-eval' https://plausible.corp.zoo.dev/js/script.tagged-events.js;connect-src 'self' https://plausible.corp.zoo.dev https://api.zoo.dev wss://api.zoo.dev https://api.dev.zoo.dev wss://api.dev.zoo.dev;object-src 'none';frame-ancestors 'none';report-uri https://csp-logger.vercel.app/csp-report;report-to csp-reporting-endpoint;" } ] }, diff --git a/vite.base.config.ts b/vite.base.config.ts index 182eec1acba..576be21f332 100644 --- a/vite.base.config.ts +++ b/vite.base.config.ts @@ -116,47 +116,55 @@ export function pluginHotRestart(command: 'reload' | 'restart'): Plugin { } } -export function csp(disable?: boolean): Plugin { - /* - 1. By default, only allow scripts from the same origin. - 2. Allow inline styles and styles from the same origin. This is how we use CSS rightnow. - 3. Allow images from any source and inline images. We fetch user profile images from any origin. - 4. Allow scripts from the same origin and from Plausible Analytics. Allow WASM execution. - 5. Allow WebSocket connections and fetches to our API. - */ - let csp = ` - default-src 'self'; - style-src 'self' 'unsafe-inline'; - img-src * 'unsafe-inline'; - script-src 'self' https://plausible.corp.zoo.dev/js/script.tagged-events.js 'wasm-unsafe-eval'; - connect-src 'self' https://plausible.corp.zoo.dev https://api.zoo.dev wss://api.zoo.dev https://api.dev.zoo.dev wss://api.dev.zoo.dev; - object-src 'none'; - frame-ancestors 'none' - ` - - /* - - 'Reporting-Endpoints': - 'csp-reporting-endpoint="https://csp-logger.vercel.app/csp-report"', - 'Content-Security-Policy-Report-Only': - "default-src 'self'; " + - "style-src 'self' 'unsafe-inline'; " + - "img-src * 'unsafe-inline'; " + - "script-src 'self' https://plausible.corp.zoo.dev/js/script.tagged-events.js 'wasm-unsafe-eval'; " + - "connect-src 'self' https://api.zoo.dev wss://api.zoo.dev https://api.dev.zoo.dev wss://api.dev.zoo.dev; " + - "object-src 'none'; " + - "frame-ancestors 'none'; " + - 'report-uri https://csp-logger.vercel.app/csp-report;' + - 'report-to csp-reporting-endpoint', - - */ +export type CspMode = + | 'electron' + | 'vercel-preview' + | 'vercel-production' + | 'local' + +export function indexHtmlCsp(mode: CspMode): Plugin { + let csp = + [ + // By default, only allow same origin. + "default-src 'self'", + // Allow inline styles and styles from the same origin. This is how we use CSS rightnow. + "style-src 'self' 'unsafe-inline'", + // Allow images from any source and inline images. We fetch user profile images from any origin. + "img-src * blob: 'unsafe-inline'", + // Allow scripts from the same origin and from Plausible Analytics. Allow WASM execution. + `script-src 'self' 'wasm-unsafe-eval' https://plausible.corp.zoo.dev/js/script.tagged-events.js${mode === 'vercel-preview' ? " https://vercel.live 'unsafe-eval'" : ''}`, + // vercel.live is used for feedback scripts in preview deployments. + ...(mode === 'vercel-preview' + ? ["frame-src 'self' https://vercel.live"] + : []), + // Allow WebSocket connections and fetches to our API. + "connect-src 'self' https://plausible.corp.zoo.dev https://api.zoo.dev wss://api.zoo.dev https://api.dev.zoo.dev wss://api.dev.zoo.dev", + // Disallow legacy stuff + "object-src 'none'", + // frame ancestors can only be blocked using HTTP headers (see vercel.json) + // "frame-ancestors 'none'", + ...(mode === 'vercel-preview' || mode == 'vercel-production' + ? [ + "frame-ancestors 'none'", + 'report-uri https://csp-logger.vercel.app/csp-report', + 'report-to csp-reporting-endpoint', + ] + : []), + ].join(';') + ';' + + console.log( + 'CSP: Production build using the Content-Security-Policy (you may copy this to vercel.json when running npx vite build): ', + csp + ) return { name: 'html-transform', transformIndexHtml(html: string) { let indexHtmlRegex = // - if (disable) { + if (mode === 'vercel-production' || mode == 'vercel-preview') { + // Web deployments that are deployed to vercel don't need a CSP in the indexHTML. + // They get it through vercel.json. return html.replace(indexHtmlRegex, '') } else { return html.replace( diff --git a/vite.config.ts b/vite.config.ts index f3ba20826e7..be04aa1f3c5 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -7,13 +7,11 @@ import version from 'vite-plugin-package-version' import topLevelAwait from 'vite-plugin-top-level-await' import viteTsconfigPaths from 'vite-tsconfig-paths' import { configDefaults, defineConfig } from 'vitest/config' -import { csp } from './vite.base.config' +import { indexHtmlCsp } from './vite.base.config' export default defineConfig(({ command, mode }) => { const runMillion = process.env.RUN_MILLION - console.log(`Vite running in ${mode} mode.`) - return { server: { open: true, @@ -80,9 +78,14 @@ export default defineConfig(({ command, mode }) => { }, plugins: [ react(), - // Web deployments that are deployed to production don't need a CSP in the indexHTML. - // They get it through vercel.json. - csp(mode == 'production'), + indexHtmlCsp( + // production means it was build using `vite build` + mode == 'production' + ? process.env.VITE_KITTYCAD_BASE_DOMAIN === 'dev.zoo.dev' + ? 'vercel-preview' + : 'vercel-production' + : 'local' + ), viteTsconfigPaths(), eslint(), version(), diff --git a/vite.renderer.config.ts b/vite.renderer.config.ts index dc07afb5ee0..30fbf5b36c7 100644 --- a/vite.renderer.config.ts +++ b/vite.renderer.config.ts @@ -5,7 +5,7 @@ import { defineConfig } from 'vite' import topLevelAwait from 'vite-plugin-top-level-await' import viteTsconfigPaths from 'vite-tsconfig-paths' -import { pluginExposeRenderer, csp } from './vite.base.config' +import { pluginExposeRenderer, indexHtmlCsp } from './vite.base.config' // https://vitejs.dev/config export default defineConfig((env) => { @@ -23,7 +23,7 @@ export default defineConfig((env) => { // Needed for electron-forge (in npm run tron:start) optimizeDeps: { esbuildOptions: { target: 'es2022' } }, plugins: [ - csp(), + indexHtmlCsp('electron'), pluginExposeRenderer(name), viteTsconfigPaths(), lezer(), From e2693117806a2ed2ea324d875ef505450e95610a Mon Sep 17 00:00:00 2001 From: Max Ammann Date: Tue, 12 Aug 2025 19:57:50 +0200 Subject: [PATCH 09/18] fix vercel csps --- vercel.json | 7 +++-- vite.base.config.ts | 75 +++++++++++++++++++++++++++------------------ 2 files changed, 50 insertions(+), 32 deletions(-) diff --git a/vercel.json b/vercel.json index 1e59e5aa5a8..abb14ed03dc 100644 --- a/vercel.json +++ b/vercel.json @@ -10,7 +10,7 @@ }, { "key": "Content-Security-Policy-Report-Only", - "value": "default-src 'self';style-src 'self' 'unsafe-inline';img-src * blob: 'unsafe-inline';script-src 'self' 'wasm-unsafe-eval' https://plausible.corp.zoo.dev/js/script.tagged-events.js;connect-src 'self' https://plausible.corp.zoo.dev https://api.zoo.dev wss://api.zoo.dev https://api.dev.zoo.dev wss://api.dev.zoo.dev;object-src 'none';frame-ancestors 'none';report-uri https://csp-logger.vercel.app/csp-report;report-to csp-reporting-endpoint;" + "value": "default-src 'self';style-src 'self' 'unsafe-inline';img-src * blob: 'unsafe-inline';connect-src 'self' https://plausible.corp.zoo.dev https://api.zoo.dev wss://api.zoo.dev https://api.dev.zoo.dev wss://api.dev.zoo.dev;object-src 'none';frame-ancestors 'none';frame-src 'self' https://vercel.live;script-src 'self' 'wasm-unsafe-eval' https://plausible.corp.zoo.dev/js/script.tagged-events.js https://vercel.live 'unsafe-eval';" } ] }, @@ -26,7 +26,10 @@ { "key": "X-Robots-Tag", "value": "noindex" - } + }, + { + "key": "Content-Security-Policy-Report-Only", + "value": "default-src 'self';style-src 'self' 'unsafe-inline';img-src * blob: 'unsafe-inline';connect-src 'self' https://plausible.corp.zoo.dev https://api.zoo.dev wss://api.zoo.dev https://api.dev.zoo.dev wss://api.dev.zoo.dev;object-src 'none';frame-ancestors 'none';script-src 'self' 'wasm-unsafe-eval' https://plausible.corp.zoo.dev/js/script.tagged-events.js;report-uri https://csp-logger.vercel.app/csp-report;report-to csp-reporting-endpoint;" } ] } ] diff --git a/vite.base.config.ts b/vite.base.config.ts index 576be21f332..d56ee7932bd 100644 --- a/vite.base.config.ts +++ b/vite.base.config.ts @@ -123,38 +123,51 @@ export type CspMode = | 'local' export function indexHtmlCsp(mode: CspMode): Plugin { - let csp = - [ - // By default, only allow same origin. - "default-src 'self'", - // Allow inline styles and styles from the same origin. This is how we use CSS rightnow. - "style-src 'self' 'unsafe-inline'", - // Allow images from any source and inline images. We fetch user profile images from any origin. - "img-src * blob: 'unsafe-inline'", - // Allow scripts from the same origin and from Plausible Analytics. Allow WASM execution. - `script-src 'self' 'wasm-unsafe-eval' https://plausible.corp.zoo.dev/js/script.tagged-events.js${mode === 'vercel-preview' ? " https://vercel.live 'unsafe-eval'" : ''}`, - // vercel.live is used for feedback scripts in preview deployments. - ...(mode === 'vercel-preview' - ? ["frame-src 'self' https://vercel.live"] - : []), - // Allow WebSocket connections and fetches to our API. - "connect-src 'self' https://plausible.corp.zoo.dev https://api.zoo.dev wss://api.zoo.dev https://api.dev.zoo.dev wss://api.dev.zoo.dev", - // Disallow legacy stuff - "object-src 'none'", - // frame ancestors can only be blocked using HTTP headers (see vercel.json) - // "frame-ancestors 'none'", - ...(mode === 'vercel-preview' || mode == 'vercel-production' - ? [ - "frame-ancestors 'none'", - 'report-uri https://csp-logger.vercel.app/csp-report', - 'report-to csp-reporting-endpoint', - ] - : []), - ].join(';') + ';' + const csp = [ + // By default, only allow same origin. + "default-src 'self'", + // Allow inline styles and styles from the same origin. This is how we use CSS rightnow. + "style-src 'self' 'unsafe-inline'", + // Allow images from any source and inline images. We fetch user profile images from any origin. + "img-src * blob: 'unsafe-inline'", + // Allow WebSocket connections and fetches to our API. + "connect-src 'self' https://plausible.corp.zoo.dev https://api.zoo.dev wss://api.zoo.dev https://api.dev.zoo.dev wss://api.dev.zoo.dev", + // Disallow legacy stuff + "object-src 'none'", + ] + + // Allow scripts from the same origin and from Plausible Analytics. Allow WASM execution. + const cspScriptBase = `script-src 'self' 'wasm-unsafe-eval' https://plausible.corp.zoo.dev/js/script.tagged-events.js` + const vercelCspBase = ["frame-ancestors 'none'"] + + const vercelCsp = + csp + .concat(vercelCspBase) + .concat( + // frame ancestors can only be blocked using HTTP headers (see vercel.json) + [ + cspScriptBase, + 'report-uri https://csp-logger.vercel.app/csp-report', + 'report-to csp-reporting-endpoint', + ] + ) + .join(';') + ';' + + console.log( + 'Content-Security-Policy for Vercel (prod) (vercel.json): ', + vercelCsp + ) console.log( - 'CSP: Production build using the Content-Security-Policy (you may copy this to vercel.json when running npx vite build): ', + 'Content-Security-Policy for Vercel (preview) (vercel.json): ', + // vercel.live is used for feedback scripts in preview deployments. csp + .concat(vercelCspBase) + .concat([ + "frame-src 'self' https://vercel.live", + `${cspScriptBase} https://vercel.live 'unsafe-eval'`, + ]) + .join(';') + ';' ) return { @@ -169,7 +182,9 @@ export function indexHtmlCsp(mode: CspMode): Plugin { } else { return html.replace( indexHtmlRegex, - `` + `` ) } }, From 650e23a562b2e1c492d85dd8730912cb90b74225 Mon Sep 17 00:00:00 2001 From: Max Ammann Date: Tue, 12 Aug 2025 23:31:25 +0200 Subject: [PATCH 10/18] cleanup env --- vite.base.config.ts | 8 ++------ vite.config.ts | 9 +-------- 2 files changed, 3 insertions(+), 14 deletions(-) diff --git a/vite.base.config.ts b/vite.base.config.ts index d56ee7932bd..864746b0dc7 100644 --- a/vite.base.config.ts +++ b/vite.base.config.ts @@ -116,11 +116,7 @@ export function pluginHotRestart(command: 'reload' | 'restart'): Plugin { } } -export type CspMode = - | 'electron' - | 'vercel-preview' - | 'vercel-production' - | 'local' +export type CspMode = 'electron' | 'vercel' | 'local' export function indexHtmlCsp(mode: CspMode): Plugin { const csp = [ @@ -175,7 +171,7 @@ export function indexHtmlCsp(mode: CspMode): Plugin { transformIndexHtml(html: string) { let indexHtmlRegex = // - if (mode === 'vercel-production' || mode == 'vercel-preview') { + if (mode == 'vercel') { // Web deployments that are deployed to vercel don't need a CSP in the indexHTML. // They get it through vercel.json. return html.replace(indexHtmlRegex, '') diff --git a/vite.config.ts b/vite.config.ts index be04aa1f3c5..010957da07d 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -78,14 +78,7 @@ export default defineConfig(({ command, mode }) => { }, plugins: [ react(), - indexHtmlCsp( - // production means it was build using `vite build` - mode == 'production' - ? process.env.VITE_KITTYCAD_BASE_DOMAIN === 'dev.zoo.dev' - ? 'vercel-preview' - : 'vercel-production' - : 'local' - ), + indexHtmlCsp(mode == process.env.VERCEL ? 'vercel' : 'local'), viteTsconfigPaths(), eslint(), version(), From 6a0ee0e02d06856970a95c599f9e8fd9bc2cf793 Mon Sep 17 00:00:00 2001 From: Max Ammann Date: Tue, 12 Aug 2025 23:36:49 +0200 Subject: [PATCH 11/18] cleanup vars and only enable in production builds --- vite.base.config.ts | 8 +++----- vite.config.ts | 2 +- vite.renderer.config.ts | 2 +- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/vite.base.config.ts b/vite.base.config.ts index 864746b0dc7..e9aa5f37a29 100644 --- a/vite.base.config.ts +++ b/vite.base.config.ts @@ -116,9 +116,7 @@ export function pluginHotRestart(command: 'reload' | 'restart'): Plugin { } } -export type CspMode = 'electron' | 'vercel' | 'local' - -export function indexHtmlCsp(mode: CspMode): Plugin { +export function indexHtmlCsp(enabled: boolean): Plugin { const csp = [ // By default, only allow same origin. "default-src 'self'", @@ -127,7 +125,7 @@ export function indexHtmlCsp(mode: CspMode): Plugin { // Allow images from any source and inline images. We fetch user profile images from any origin. "img-src * blob: 'unsafe-inline'", // Allow WebSocket connections and fetches to our API. - "connect-src 'self' https://plausible.corp.zoo.dev https://api.zoo.dev wss://api.zoo.dev https://api.dev.zoo.dev wss://api.dev.zoo.dev", + "connect-src 'self' https://plausible.corp.zoo.dev https://api.zoo.dev wss://api.zoo.dev https://api.dev.zoo.dev wss://api.dev.zoo.dev https://api.zoogov.dev wss://api.zoogov.dev", // Disallow legacy stuff "object-src 'none'", ] @@ -171,7 +169,7 @@ export function indexHtmlCsp(mode: CspMode): Plugin { transformIndexHtml(html: string) { let indexHtmlRegex = // - if (mode == 'vercel') { + if (!enabled) { // Web deployments that are deployed to vercel don't need a CSP in the indexHTML. // They get it through vercel.json. return html.replace(indexHtmlRegex, '') diff --git a/vite.config.ts b/vite.config.ts index 010957da07d..82814873325 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -78,7 +78,7 @@ export default defineConfig(({ command, mode }) => { }, plugins: [ react(), - indexHtmlCsp(mode == process.env.VERCEL ? 'vercel' : 'local'), + indexHtmlCsp(mode != process.env.VERCEL && mode === 'production'), viteTsconfigPaths(), eslint(), version(), diff --git a/vite.renderer.config.ts b/vite.renderer.config.ts index 30fbf5b36c7..68210b751f8 100644 --- a/vite.renderer.config.ts +++ b/vite.renderer.config.ts @@ -23,7 +23,7 @@ export default defineConfig((env) => { // Needed for electron-forge (in npm run tron:start) optimizeDeps: { esbuildOptions: { target: 'es2022' } }, plugins: [ - indexHtmlCsp('electron'), + indexHtmlCsp(true), pluginExposeRenderer(name), viteTsconfigPaths(), lezer(), From f9df83a6afe9eccd5b38647e57eac6b4faa98117 Mon Sep 17 00:00:00 2001 From: Max Ammann Date: Tue, 12 Aug 2025 23:48:02 +0200 Subject: [PATCH 12/18] swap csps --- vercel.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/vercel.json b/vercel.json index abb14ed03dc..966b54e0e68 100644 --- a/vercel.json +++ b/vercel.json @@ -10,7 +10,7 @@ }, { "key": "Content-Security-Policy-Report-Only", - "value": "default-src 'self';style-src 'self' 'unsafe-inline';img-src * blob: 'unsafe-inline';connect-src 'self' https://plausible.corp.zoo.dev https://api.zoo.dev wss://api.zoo.dev https://api.dev.zoo.dev wss://api.dev.zoo.dev;object-src 'none';frame-ancestors 'none';frame-src 'self' https://vercel.live;script-src 'self' 'wasm-unsafe-eval' https://plausible.corp.zoo.dev/js/script.tagged-events.js https://vercel.live 'unsafe-eval';" + "value": "default-src 'self';style-src 'self' 'unsafe-inline';img-src * blob: 'unsafe-inline';connect-src 'self' https://plausible.corp.zoo.dev https://api.zoo.dev wss://api.zoo.dev https://api.dev.zoo.dev wss://api.dev.zoo.dev;object-src 'none';frame-ancestors 'none';script-src 'self' 'wasm-unsafe-eval' https://plausible.corp.zoo.dev/js/script.tagged-events.js;report-uri https://csp-logger.vercel.app/csp-report;report-to csp-reporting-endpoint;" } } ] }, @@ -29,7 +29,8 @@ }, { "key": "Content-Security-Policy-Report-Only", - "value": "default-src 'self';style-src 'self' 'unsafe-inline';img-src * blob: 'unsafe-inline';connect-src 'self' https://plausible.corp.zoo.dev https://api.zoo.dev wss://api.zoo.dev https://api.dev.zoo.dev wss://api.dev.zoo.dev;object-src 'none';frame-ancestors 'none';script-src 'self' 'wasm-unsafe-eval' https://plausible.corp.zoo.dev/js/script.tagged-events.js;report-uri https://csp-logger.vercel.app/csp-report;report-to csp-reporting-endpoint;" } + "value": "default-src 'self';style-src 'self' 'unsafe-inline';img-src * blob: 'unsafe-inline';connect-src 'self' https://plausible.corp.zoo.dev https://api.zoo.dev wss://api.zoo.dev https://api.dev.zoo.dev wss://api.dev.zoo.dev;object-src 'none';frame-ancestors 'none';frame-src 'self' https://vercel.live;script-src 'self' 'wasm-unsafe-eval' https://plausible.corp.zoo.dev/js/script.tagged-events.js https://vercel.live 'unsafe-eval';" + } ] } ] From a24759116bcab7eec149360f48c5a9698bd58af5 Mon Sep 17 00:00:00 2001 From: Max Ammann Date: Wed, 13 Aug 2025 10:57:03 +0200 Subject: [PATCH 13/18] update vercel json --- vercel.json | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/vercel.json b/vercel.json index 966b54e0e68..5f5086c7078 100644 --- a/vercel.json +++ b/vercel.json @@ -3,14 +3,21 @@ "headers": [ { "source": "/(.*)", + "has": [ + { + "type": "host", + "value": "app.zoo.dev" + } + ], "headers": [ { "key": "Reporting-Endpoints", "value": "csp-reporting-endpoint=\"https://csp-logger.vercel.app/csp-report\"" }, + // Copy this CSP from the `npx vite build` output. This is the production CSP. { "key": "Content-Security-Policy-Report-Only", - "value": "default-src 'self';style-src 'self' 'unsafe-inline';img-src * blob: 'unsafe-inline';connect-src 'self' https://plausible.corp.zoo.dev https://api.zoo.dev wss://api.zoo.dev https://api.dev.zoo.dev wss://api.dev.zoo.dev;object-src 'none';frame-ancestors 'none';script-src 'self' 'wasm-unsafe-eval' https://plausible.corp.zoo.dev/js/script.tagged-events.js;report-uri https://csp-logger.vercel.app/csp-report;report-to csp-reporting-endpoint;" } + "value": "default-src 'self';style-src 'self' 'unsafe-inline';img-src * blob: 'unsafe-inline';connect-src 'self' https://plausible.corp.zoo.dev https://api.zoo.dev wss://api.zoo.dev https://api.dev.zoo.dev wss://api.dev.zoo.dev;object-src 'none';frame-ancestors 'none';script-src 'self' 'wasm-unsafe-eval' https://plausible.corp.zoo.dev/js/script.tagged-events.js;report-uri https://csp-logger.vercel.app/csp-report;report-to csp-reporting-endpoint;" } ] }, @@ -27,6 +34,7 @@ "key": "X-Robots-Tag", "value": "noindex" }, + // Copy this CSP from the `npx vite build` output. This is the preview CSP. { "key": "Content-Security-Policy-Report-Only", "value": "default-src 'self';style-src 'self' 'unsafe-inline';img-src * blob: 'unsafe-inline';connect-src 'self' https://plausible.corp.zoo.dev https://api.zoo.dev wss://api.zoo.dev https://api.dev.zoo.dev wss://api.dev.zoo.dev;object-src 'none';frame-ancestors 'none';frame-src 'self' https://vercel.live;script-src 'self' 'wasm-unsafe-eval' https://plausible.corp.zoo.dev/js/script.tagged-events.js https://vercel.live 'unsafe-eval';" From 4aa265667faa81a65f3fbdab93e7106ca7a2c102 Mon Sep 17 00:00:00 2001 From: Max Ammann Date: Wed, 13 Aug 2025 10:57:59 +0200 Subject: [PATCH 14/18] update vercel json --- vercel.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vercel.json b/vercel.json index 5f5086c7078..b65e1bb5160 100644 --- a/vercel.json +++ b/vercel.json @@ -14,8 +14,8 @@ "key": "Reporting-Endpoints", "value": "csp-reporting-endpoint=\"https://csp-logger.vercel.app/csp-report\"" }, - // Copy this CSP from the `npx vite build` output. This is the production CSP. { + "_comment": "Copy this CSP from the `npx vite build` output. This is the production CSP.", "key": "Content-Security-Policy-Report-Only", "value": "default-src 'self';style-src 'self' 'unsafe-inline';img-src * blob: 'unsafe-inline';connect-src 'self' https://plausible.corp.zoo.dev https://api.zoo.dev wss://api.zoo.dev https://api.dev.zoo.dev wss://api.dev.zoo.dev;object-src 'none';frame-ancestors 'none';script-src 'self' 'wasm-unsafe-eval' https://plausible.corp.zoo.dev/js/script.tagged-events.js;report-uri https://csp-logger.vercel.app/csp-report;report-to csp-reporting-endpoint;" } @@ -34,8 +34,8 @@ "key": "X-Robots-Tag", "value": "noindex" }, - // Copy this CSP from the `npx vite build` output. This is the preview CSP. { + "_comment": "Copy this CSP from the `npx vite build` output. This is the preview CSP.", "key": "Content-Security-Policy-Report-Only", "value": "default-src 'self';style-src 'self' 'unsafe-inline';img-src * blob: 'unsafe-inline';connect-src 'self' https://plausible.corp.zoo.dev https://api.zoo.dev wss://api.zoo.dev https://api.dev.zoo.dev wss://api.dev.zoo.dev;object-src 'none';frame-ancestors 'none';frame-src 'self' https://vercel.live;script-src 'self' 'wasm-unsafe-eval' https://plausible.corp.zoo.dev/js/script.tagged-events.js https://vercel.live 'unsafe-eval';" } From 8cdac65499fd78671c5cc3f11effb9a13d313e2b Mon Sep 17 00:00:00 2001 From: Max Ammann Date: Wed, 13 Aug 2025 10:58:30 +0200 Subject: [PATCH 15/18] update vercel json --- vercel.json | 2 -- 1 file changed, 2 deletions(-) diff --git a/vercel.json b/vercel.json index b65e1bb5160..662f6fbada8 100644 --- a/vercel.json +++ b/vercel.json @@ -15,7 +15,6 @@ "value": "csp-reporting-endpoint=\"https://csp-logger.vercel.app/csp-report\"" }, { - "_comment": "Copy this CSP from the `npx vite build` output. This is the production CSP.", "key": "Content-Security-Policy-Report-Only", "value": "default-src 'self';style-src 'self' 'unsafe-inline';img-src * blob: 'unsafe-inline';connect-src 'self' https://plausible.corp.zoo.dev https://api.zoo.dev wss://api.zoo.dev https://api.dev.zoo.dev wss://api.dev.zoo.dev;object-src 'none';frame-ancestors 'none';script-src 'self' 'wasm-unsafe-eval' https://plausible.corp.zoo.dev/js/script.tagged-events.js;report-uri https://csp-logger.vercel.app/csp-report;report-to csp-reporting-endpoint;" } @@ -35,7 +34,6 @@ "value": "noindex" }, { - "_comment": "Copy this CSP from the `npx vite build` output. This is the preview CSP.", "key": "Content-Security-Policy-Report-Only", "value": "default-src 'self';style-src 'self' 'unsafe-inline';img-src * blob: 'unsafe-inline';connect-src 'self' https://plausible.corp.zoo.dev https://api.zoo.dev wss://api.zoo.dev https://api.dev.zoo.dev wss://api.dev.zoo.dev;object-src 'none';frame-ancestors 'none';frame-src 'self' https://vercel.live;script-src 'self' 'wasm-unsafe-eval' https://plausible.corp.zoo.dev/js/script.tagged-events.js https://vercel.live 'unsafe-eval';" } From 786f6b38d5087b81b7f37dde69616d96f4a69c1c Mon Sep 17 00:00:00 2001 From: Max Ammann Date: Wed, 13 Aug 2025 11:33:06 +0200 Subject: [PATCH 16/18] fix vercel detection --- vite.base.config.ts | 10 +++++----- vite.config.ts | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/vite.base.config.ts b/vite.base.config.ts index e9aa5f37a29..744729611af 100644 --- a/vite.base.config.ts +++ b/vite.base.config.ts @@ -131,7 +131,7 @@ export function indexHtmlCsp(enabled: boolean): Plugin { ] // Allow scripts from the same origin and from Plausible Analytics. Allow WASM execution. - const cspScriptBase = `script-src 'self' 'wasm-unsafe-eval' https://plausible.corp.zoo.dev/js/script.tagged-events.js` + const cspScriptBase = "script-src 'self' 'wasm-unsafe-eval' https://plausible.corp.zoo.dev/js/script.tagged-events.js" const vercelCspBase = ["frame-ancestors 'none'"] const vercelCsp = @@ -145,7 +145,7 @@ export function indexHtmlCsp(enabled: boolean): Plugin { 'report-to csp-reporting-endpoint', ] ) - .join(';') + ';' + .join('; ') + ';' console.log( 'Content-Security-Policy for Vercel (prod) (vercel.json): ', @@ -159,9 +159,9 @@ export function indexHtmlCsp(enabled: boolean): Plugin { .concat(vercelCspBase) .concat([ "frame-src 'self' https://vercel.live", - `${cspScriptBase} https://vercel.live 'unsafe-eval'`, + `${cspScriptBase} https://vercel.live/_next-live/feedback/feedback.js 'unsafe-eval'`, ]) - .join(';') + ';' + .join('; ') + ';' ) return { @@ -177,7 +177,7 @@ export function indexHtmlCsp(enabled: boolean): Plugin { return html.replace( indexHtmlRegex, `` ) } diff --git a/vite.config.ts b/vite.config.ts index 82814873325..f694609a678 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -78,7 +78,7 @@ export default defineConfig(({ command, mode }) => { }, plugins: [ react(), - indexHtmlCsp(mode != process.env.VERCEL && mode === 'production'), + indexHtmlCsp(process.env.VERCEL && mode === 'production'), viteTsconfigPaths(), eslint(), version(), From ab8e2b48846fdcc687c0e43a01ad73c50176b0df Mon Sep 17 00:00:00 2001 From: Max Ammann Date: Wed, 13 Aug 2025 11:44:58 +0200 Subject: [PATCH 17/18] also report for preview --- vercel.json | 8 +++-- vite.base.config.ts | 73 +++++++++++++++++++++++++++++++++------------ 2 files changed, 60 insertions(+), 21 deletions(-) diff --git a/vercel.json b/vercel.json index 662f6fbada8..b2e6b76255e 100644 --- a/vercel.json +++ b/vercel.json @@ -16,7 +16,7 @@ }, { "key": "Content-Security-Policy-Report-Only", - "value": "default-src 'self';style-src 'self' 'unsafe-inline';img-src * blob: 'unsafe-inline';connect-src 'self' https://plausible.corp.zoo.dev https://api.zoo.dev wss://api.zoo.dev https://api.dev.zoo.dev wss://api.dev.zoo.dev;object-src 'none';frame-ancestors 'none';script-src 'self' 'wasm-unsafe-eval' https://plausible.corp.zoo.dev/js/script.tagged-events.js;report-uri https://csp-logger.vercel.app/csp-report;report-to csp-reporting-endpoint;" + "value": "default-src 'self'; style-src 'self' 'unsafe-inline'; img-src * blob: 'unsafe-inline'; connect-src 'self' https://plausible.corp.zoo.dev https://api.zoo.dev wss://api.zoo.dev https://api.dev.zoo.dev wss://api.dev.zoo.dev https://api.zoogov.dev wss://api.zoogov.dev; object-src 'none'; frame-ancestors 'none'; script-src 'self' 'wasm-unsafe-eval' https://plausible.corp.zoo.dev/js/script.tagged-events.js; report-uri https://csp-logger.vercel.app/csp-report; report-to csp-reporting-endpoint;" } ] }, @@ -33,9 +33,13 @@ "key": "X-Robots-Tag", "value": "noindex" }, + { + "key": "Reporting-Endpoints", + "value": "csp-reporting-endpoint=\"https://csp-logger.vercel.app/csp-report\"" + }, { "key": "Content-Security-Policy-Report-Only", - "value": "default-src 'self';style-src 'self' 'unsafe-inline';img-src * blob: 'unsafe-inline';connect-src 'self' https://plausible.corp.zoo.dev https://api.zoo.dev wss://api.zoo.dev https://api.dev.zoo.dev wss://api.dev.zoo.dev;object-src 'none';frame-ancestors 'none';frame-src 'self' https://vercel.live;script-src 'self' 'wasm-unsafe-eval' https://plausible.corp.zoo.dev/js/script.tagged-events.js https://vercel.live 'unsafe-eval';" + "value": "default-src 'self'; style-src 'self' 'unsafe-inline'; img-src * blob: 'unsafe-inline'; connect-src 'self' https://plausible.corp.zoo.dev https://api.zoo.dev wss://api.zoo.dev https://api.dev.zoo.dev wss://api.dev.zoo.dev https://api.zoogov.dev wss://api.zoogov.dev; object-src 'none'; frame-ancestors 'none'; frame-src 'self' https://vercel.live; script-src 'self' 'wasm-unsafe-eval' https://plausible.corp.zoo.dev/js/script.tagged-events.js https://vercel.live/_next-live/feedback/feedback.js 'unsafe-eval'; report-uri https://csp-logger.vercel.app/csp-report; report-to csp-reporting-endpoint;" } ] } diff --git a/vite.base.config.ts b/vite.base.config.ts index 744729611af..f96b67e90d9 100644 --- a/vite.base.config.ts +++ b/vite.base.config.ts @@ -131,37 +131,72 @@ export function indexHtmlCsp(enabled: boolean): Plugin { ] // Allow scripts from the same origin and from Plausible Analytics. Allow WASM execution. - const cspScriptBase = "script-src 'self' 'wasm-unsafe-eval' https://plausible.corp.zoo.dev/js/script.tagged-events.js" + const cspScriptBase = + "script-src 'self' 'wasm-unsafe-eval' https://plausible.corp.zoo.dev/js/script.tagged-events.js" + + // frame ancestors can only be blocked using HTTP headers (see vercel.json) const vercelCspBase = ["frame-ancestors 'none'"] + const cspReporting = [ + 'report-uri https://csp-logger.vercel.app/csp-report', + 'report-to csp-reporting-endpoint', + ] + const vercelCsp = csp .concat(vercelCspBase) - .concat( - // frame ancestors can only be blocked using HTTP headers (see vercel.json) - [ - cspScriptBase, - 'report-uri https://csp-logger.vercel.app/csp-report', - 'report-to csp-reporting-endpoint', - ] - ) + .concat([cspScriptBase]) + .concat(cspReporting) .join('; ') + ';' + const reportingEndpoints = { + key: 'Reporting-Endpoints', + value: 'csp-reporting-endpoint="https://csp-logger.vercel.app/csp-report"', + } + console.log( - 'Content-Security-Policy for Vercel (prod) (vercel.json): ', + 'Content-Security-Policy for Vercel (prod) (vercel.json):', vercelCsp ) console.log( - 'Content-Security-Policy for Vercel (preview) (vercel.json): ', - // vercel.live is used for feedback scripts in preview deployments. - csp - .concat(vercelCspBase) - .concat([ - "frame-src 'self' https://vercel.live", - `${cspScriptBase} https://vercel.live/_next-live/feedback/feedback.js 'unsafe-eval'`, - ]) - .join('; ') + ';' + JSON.stringify( + [ + reportingEndpoints, + { + key: 'Content-Security-Policy-Report-Only', + value: vercelCsp, + }, + ], + null, + 2 + ) + ) + + console.log('Content-Security-Policy for Vercel (preview) (vercel.json):') + + console.log( + JSON.stringify( + [ + reportingEndpoints, + { + key: 'Content-Security-Policy-Report-Only', + value: + csp + .concat(vercelCspBase) + .concat([ + // vercel.live is used for feedback scripts in preview deployments. + "frame-src 'self' https://vercel.live", + `${cspScriptBase} https://vercel.live/_next-live/feedback/feedback.js 'unsafe-eval'`, + ]) + .concat(cspReporting) + .join('; ') + ';', + }, + ], + + null, + 2 + ) ) return { From 131b2dc1699a7fbfa66010b55a651f3ea68aa20f Mon Sep 17 00:00:00 2001 From: Max Ammann Date: Wed, 13 Aug 2025 11:56:22 +0200 Subject: [PATCH 18/18] fix vercel detection --- vite.config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vite.config.ts b/vite.config.ts index f694609a678..56a0a246bd1 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -78,7 +78,7 @@ export default defineConfig(({ command, mode }) => { }, plugins: [ react(), - indexHtmlCsp(process.env.VERCEL && mode === 'production'), + indexHtmlCsp(!process.env.VERCEL && mode === 'production'), viteTsconfigPaths(), eslint(), version(),