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: {