openvibers/openvibe.tools Commits

Every tool host's CSP lets Cloudflare's analytics beacon load and report (#238)

OP OpenVibers committed 6 days ago · 167be3429e · 7 files, +36 −11

The text, image, audio, docs and food apps refused static.cloudflareinsights.com, so every page on their own hosts
(case.openvibe.tools and the rest, where /tool/:id now 301s) logged a CSP error (11-07 browser sweep of every site's
inner pages); maps loaded the beacon but refused its report. A test keeps every app's CSP in line.

Changes

ddiff --git a/apps/_shared/test/csp-cloudflare-beacon.test.js b/apps/_shared/test/csp-cloudflare-beacon.test.js
nnew file mode 100644
iindex 0000000..a8d947e
---- /dev/null
++++ b/apps/_shared/test/csp-cloudflare-beacon.test.js
@@@ -0,0 +1,25 @@
++'use strict';
++/**
++ * Every app's Content-Security-Policy lets Cloudflare's analytics beacon load and report (11-07): the text, image,
++ * audio, docs and food apps refused static.cloudflareinsights.com, so every page on their own hosts
++ * (case.openvibe.tools and the rest) logged a CSP error, found by the browser sweep of every site's inner pages.
++ * node apps/_shared/test/csp-cloudflare-beacon.test.js
++ */
++const assert = require('assert');
++const fs = require('fs');
++const path = require('path');
++
++const APPS = path.join(__dirname, '..', '..');
++const apps = fs.readdirSync(APPS).filter((a) => fs.existsSync(path.join(APPS, a, 'server', 'index.js')));
++let checked = 0;
++apps.forEach((a) => {
++ const src = fs.readFileSync(path.join(APPS, a, 'server', 'index.js'), 'utf8');
++ const script = src.match(/scriptSrc:\s*\[([^\]\n]*)\]/);
++ if (!script) return; // an app that sets no CSP of its own
++ checked++;
++ assert.ok(/static\.cloudflareinsights\.com/.test(script[1]), `${a}: scriptSrc allows Cloudflare's beacon`);
++ const connect = src.match(/connectSrc:\s*\[([^\]\n]*)\]/);
++ if (connect) assert.ok(/cloudflareinsights\.com/.test(connect[1]), `${a}: connectSrc lets the beacon report`);
++});
++assert.ok(checked >= 5, `found the apps' CSPs (${checked})`);
++console.log(`csp cloudflare beacon: ${checked} apps let the beacon load and report`);
ddiff --git a/apps/audio/server/index.js b/apps/audio/server/index.js
iindex 44a003d..d2e9ef2 100644
---- a/apps/audio/server/index.js
++++ b/apps/audio/server/index.js
@@@ -95,14 +95,14 @@ app.use(helmet({
contentSecurityPolicy: {
directives: {
defaultSrc: ["'self'"],
-- scriptSrc: ["'self'", "'unsafe-inline'", "https://fonts.googleapis.com", "https://openvibe.network"],
++ scriptSrc: ["'self'", "'unsafe-inline'", "https://fonts.googleapis.com", "https://openvibe.network", "https://static.cloudflareinsights.com"],
styleSrc: ["'self'", "'unsafe-inline'", "https://fonts.googleapis.com", "https://fonts.gstatic.com"],
fontSrc: ["'self'", "https://fonts.gstatic.com"],
imgSrc: ["'self'", "data:", "blob:", jobsRuntime.mediaOrigin()], // job result previews are 302s to Media
mediaSrc: ["'self'", "blob:", jobsRuntime.mediaOrigin()],
// openvibe.events: release notifications (release-watch's EventSource, openvibe-shared 2.13.0).
// The navbar's Messages count asks Chat (openvibe-shared 4.130.0).
-- connectSrc: ["'self'", "https://openvibe.chat", "https://openvibe.network", "https://*.openvibe.tools", "https://openvibe.events"],
++ connectSrc: ["'self'", "https://openvibe.chat", "https://openvibe.network", "https://*.openvibe.tools", "https://openvibe.events", "https://cloudflareinsights.com"],
workerSrc: ["'self'", "blob:"],
scriptSrcAttr: ["'unsafe-inline'"],
},
ddiff --git a/apps/docs/server/index.js b/apps/docs/server/index.js
iindex 35a8331..15d2b7f 100644
---- a/apps/docs/server/index.js
++++ b/apps/docs/server/index.js
@@@ -112,13 +112,13 @@ app.use(helmet({
contentSecurityPolicy: {
directives: {
defaultSrc: ["'self'"],
-- scriptSrc: ["'self'", "'unsafe-inline'", "https://fonts.googleapis.com", "https://openvibe.network"],
++ scriptSrc: ["'self'", "'unsafe-inline'", "https://fonts.googleapis.com", "https://openvibe.network", "https://static.cloudflareinsights.com"],
styleSrc: ["'self'", "'unsafe-inline'", "https://fonts.googleapis.com", "https://fonts.gstatic.com"],
fontSrc: ["'self'", "https://fonts.gstatic.com"],
imgSrc: ["'self'", "data:", "blob:"],
// openvibe.events: release notifications (release-watch's EventSource, openvibe-shared 2.13.0).
// The navbar's Messages count asks Chat (openvibe-shared 4.130.0).
-- connectSrc: ["'self'", "https://openvibe.chat", "https://openvibe.network", "https://*.openvibe.tools", "https://openvibe.events"],
++ connectSrc: ["'self'", "https://openvibe.chat", "https://openvibe.network", "https://*.openvibe.tools", "https://openvibe.events", "https://cloudflareinsights.com"],
workerSrc: ["'self'", "blob:"],
scriptSrcAttr: ["'unsafe-inline'"],
},
ddiff --git a/apps/food/server/index.js b/apps/food/server/index.js
iindex 7539b3a..1139778 100644
---- a/apps/food/server/index.js
++++ b/apps/food/server/index.js
@@@ -85,13 +85,13 @@ app.use(helmet({
contentSecurityPolicy: {
directives: {
defaultSrc: ["'self'"],
-- scriptSrc: ["'self'", "'unsafe-inline'", 'cdn.jsdelivr.net', 'unpkg.com', 'fonts.googleapis.com', 'https://openvibe.network'],
++ scriptSrc: ["'self'", "'unsafe-inline'", 'cdn.jsdelivr.net', 'unpkg.com', 'fonts.googleapis.com', 'https://openvibe.network', "https://static.cloudflareinsights.com"],
styleSrc: ["'self'", "'unsafe-inline'", 'cdn.jsdelivr.net', 'unpkg.com', 'fonts.googleapis.com', 'fonts.gstatic.com'],
fontSrc: ["'self'", 'fonts.gstatic.com'],
imgSrc: ["'self'", 'data:', 'image.tmdb.org', '*.tile.openstreetmap.org', '*.basemaps.cartocdn.com', 'server.arcgisonline.com'],
// openvibe.events: release notifications (release-watch's EventSource, openvibe-shared 2.13.0).
// The navbar's Messages count asks Chat (openvibe-shared 4.130.0).
-- connectSrc: ["'self'", 'https://openvibe.chat', 'nominatim.openstreetmap.org', 'https://openvibe.network', 'https://openvibe.events'],
++ connectSrc: ["'self'", 'https://openvibe.chat', 'nominatim.openstreetmap.org', 'https://openvibe.network', 'https://openvibe.events', "https://cloudflareinsights.com"],
scriptSrcAttr: ["'unsafe-inline'"],
},
},
ddiff --git a/apps/img/server/index.js b/apps/img/server/index.js
iindex 09354cf..366be15 100644
---- a/apps/img/server/index.js
++++ b/apps/img/server/index.js
@@@ -101,13 +101,13 @@ app.use(helmet({
contentSecurityPolicy: {
directives: {
defaultSrc: ["'self'"],
-- scriptSrc: ["'self'", "'unsafe-inline'", "https://fonts.googleapis.com", "https://openvibe.network"],
++ scriptSrc: ["'self'", "'unsafe-inline'", "https://fonts.googleapis.com", "https://openvibe.network", "https://static.cloudflareinsights.com"],
styleSrc: ["'self'", "'unsafe-inline'", "https://fonts.googleapis.com", "https://fonts.gstatic.com"],
fontSrc: ["'self'", "https://fonts.gstatic.com"],
imgSrc: ["'self'", "data:", "blob:", jobsRuntime.mediaOrigin()], // job result previews are 302s to Media
// openvibe.events: release notifications (release-watch's EventSource, openvibe-shared 2.13.0).
// The navbar's Messages count asks Chat (openvibe-shared 4.130.0).
-- connectSrc: ["'self'", "https://openvibe.chat", "https://openvibe.network", "https://*.openvibe.tools", "https://openvibe.events"],
++ connectSrc: ["'self'", "https://openvibe.chat", "https://openvibe.network", "https://*.openvibe.tools", "https://openvibe.events", "https://cloudflareinsights.com"],
workerSrc: ["'self'", "blob:"],
scriptSrcAttr: ["'unsafe-inline'"],
},
ddiff --git a/apps/maps/server/index.js b/apps/maps/server/index.js
iindex e3ebe3c..c8aa59c 100644
---- a/apps/maps/server/index.js
++++ b/apps/maps/server/index.js
@@@ -83,7 +83,7 @@ app.use(helmet({
imgSrc: ["'self'", "data:", "blob:", "*.tile.openstreetmap.org", "*.basemaps.cartocdn.com", "server.arcgisonline.com", "image.tmdb.org", "*.wp.com"],
// openvibe.events: release notifications (release-watch's EventSource, openvibe-shared 2.13.0).
// The navbar's Messages count asks Chat (openvibe-shared 4.130.0).
-- connectSrc: ["'self'", "https://openvibe.chat", "nominatim.openstreetmap.org", "api.weather.gov", "api.open-meteo.com", "*.tile.openstreetmap.org", "*.basemaps.cartocdn.com", "server.arcgisonline.com", "https://openvibe.network", "https://openvibe.events"],
++ connectSrc: ["'self'", "https://openvibe.chat", "nominatim.openstreetmap.org", "api.weather.gov", "api.open-meteo.com", "*.tile.openstreetmap.org", "*.basemaps.cartocdn.com", "server.arcgisonline.com", "https://openvibe.network", "https://openvibe.events", "https://cloudflareinsights.com"],
fontSrc: ["'self'", "fonts.gstatic.com", "cdn.jsdelivr.net"],
frameSrc: ["'none'"],
scriptSrcAttr: ["'unsafe-inline'"],
ddiff --git a/apps/text/server/index.js b/apps/text/server/index.js
iindex 2ff5f1a..96e57dd 100644
---- a/apps/text/server/index.js
++++ b/apps/text/server/index.js
@@@ -64,13 +64,13 @@ app.use(helmet({
contentSecurityPolicy: {
directives: {
defaultSrc: ["'self'"],
-- scriptSrc: ["'self'", "'unsafe-inline'", "cdn.jsdelivr.net", "fonts.googleapis.com", "https://openvibe.network"],
++ scriptSrc: ["'self'", "'unsafe-inline'", "cdn.jsdelivr.net", "fonts.googleapis.com", "https://openvibe.network", "https://static.cloudflareinsights.com"],
styleSrc: ["'self'", "'unsafe-inline'", "fonts.googleapis.com", "fonts.gstatic.com"],
fontSrc: ["'self'", "fonts.gstatic.com"],
imgSrc: ["'self'", "data:", "blob:"],
// openvibe.events: release notifications (release-watch's EventSource, openvibe-shared 2.13.0).
// The navbar's Messages count asks Chat (openvibe-shared 4.130.0).
-- connectSrc: ["'self'", "https://openvibe.chat", "https://openvibe.network", "https://api.exchangerate-api.com", "https://openvibe.events"],
++ connectSrc: ["'self'", "https://openvibe.chat", "https://openvibe.network", "https://api.exchangerate-api.com", "https://openvibe.events", "https://cloudflareinsights.com"],
frameSrc: ["'none'"],
scriptSrcAttr: ["'unsafe-inline'"],
},