From a0b47000f3cb4ca06adfec5d98ffae1dd807808f Mon Sep 17 00:00:00 2001 From: ScreenTinker Date: Wed, 8 Jul 2026 13:03:56 -0500 Subject: [PATCH] feat(csp): allow Cloudflare Web Analytics beacon to load AND report MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The dashboard CSP (script-src 'self') blocked Cloudflare's Web Analytics beacon. Add the two exact entries the beacon needs (both required — script-only loads but silently can't report): - script-src: https://static.cloudflareinsights.com (beacon script loads) - connect-src: https://cloudflareinsights.com (beacon POSTs analytics back) Exact domains, no wildcards. connect-src already had 'wss:'/'ws:' (socket.io) + 'https:' — those stay, so the dashboard socket is unaffected; the explicit CF domain documents intent and survives any future tightening of the broad 'https:'. Co-Authored-By: Claude Opus 4.8 (1M context) --- server/server.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/server/server.js b/server/server.js index d186afb..6b56a41 100644 --- a/server/server.js +++ b/server/server.js @@ -90,13 +90,17 @@ const dashboardCsp = helmet.contentSecurityPolicy({ useDefaults: true, directives: { defaultSrc: ["'self'"], - scriptSrc: ["'self'"], + // Cloudflare Web Analytics: the beacon SCRIPT (static.cloudflareinsights.com) must be allowed to + // load, AND the beacon must be allowed to POST its data back (connect-src -> cloudflareinsights.com). + // Both are required — with only the script entry the beacon loads but silently can't report. + scriptSrc: ["'self'", 'https://static.cloudflareinsights.com'], scriptSrcAttr: ["'unsafe-inline'"], styleSrc: ["'self'", "'unsafe-inline'"], styleSrcAttr: ["'unsafe-inline'"], imgSrc: ["'self'", 'data:', 'blob:', 'https:'], mediaSrc: ["'self'", 'blob:', 'https:'], - connectSrc: ["'self'", 'wss:', 'ws:', 'https:'], + // 'wss:'/'ws:' keep the dashboard's socket.io connection working; the CF entry lets the beacon report. + connectSrc: ["'self'", 'wss:', 'ws:', 'https:', 'https://cloudflareinsights.com'], fontSrc: ["'self'", 'data:'], frameSrc: ["'self'", 'https://www.youtube.com', 'https://youtube.com'], objectSrc: ["'none'"],