From c91d99de801f176f5ff55840ebeaddf9c9064379 Mon Sep 17 00:00:00 2001 From: Alf Eaton Date: Thu, 3 Oct 2024 13:04:46 +0100 Subject: [PATCH] Allow additional CSP directives to be defined for specific views (#19550) GitOrigin-RevId: 19bf1004479b5106e64e9c13d58d69e328cc12f1 --- services/web/app/src/infrastructure/CSP.js | 16 ++++++++++++++-- services/web/config/settings.defaults.js | 3 +++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/services/web/app/src/infrastructure/CSP.js b/services/web/app/src/infrastructure/CSP.js index 436cdd1bb0..423154d623 100644 --- a/services/web/app/src/infrastructure/CSP.js +++ b/services/web/app/src/infrastructure/CSP.js @@ -6,6 +6,7 @@ module.exports = function ({ reportPercentage, reportOnly = false, exclude = [], + viewDirectives = {}, }) { const header = reportOnly ? 'Content-Security-Policy-Report-Only' @@ -37,7 +38,12 @@ module.exports = function ({ res.locals.scriptNonce = scriptNonce - const policy = buildViewPolicy(scriptNonce, reportPercentage, reportUri) + const policy = buildViewPolicy( + scriptNonce, + reportPercentage, + reportUri, + viewDirectives[view] + ) // Note: https://csp-evaluator.withgoogle.com/ is useful for checking the policy @@ -72,11 +78,17 @@ const buildDefaultPolicy = (reportUri, styleSrc) => { return directives.join('; ') } -const buildViewPolicy = (scriptNonce, reportPercentage, reportUri) => { +const buildViewPolicy = ( + scriptNonce, + reportPercentage, + reportUri, + viewDirectives +) => { const directives = [ `script-src 'nonce-${scriptNonce}' 'unsafe-inline' 'strict-dynamic' https: 'report-sample'`, // only allow scripts from certain sources `object-src 'none'`, // forbid loading an "object" element `base-uri 'none'`, // forbid setting a "base" element + ...(viewDirectives ?? []), ] if (reportUri) { diff --git a/services/web/config/settings.defaults.js b/services/web/config/settings.defaults.js index c72c99e28a..e1f22ef40d 100644 --- a/services/web/config/settings.defaults.js +++ b/services/web/config/settings.defaults.js @@ -977,6 +977,9 @@ module.exports = { reportPercentage: parseFloat(process.env.CSP_REPORT_PERCENTAGE) || 0, reportUri: process.env.CSP_REPORT_URI, exclude: [], + viewDirectives: { + 'app/views/project/ide-react': [`img-src 'self' data: blob:`], + }, }, unsupportedBrowsers: {