I am adding the following CSP directives for an express app using helmet. and in some cases, i am loading dynamically a script tag in my react app using react-helmet. but the CSP blocks the script from running. giving the following error in client console:
Refused to load the script 'data:application/javascript;base64,KCgpID0+IHsKICAgICd1c2Ugc3RyaWN0JwogICAgY29uc3Qgbm9vcCA9ICgpID0+IHt9CiAgICBjb25zdCBkYXRhbGF5ZXIgPSB3aW5kb3cuZGF0YUxheWVyCiAgICB3aW5kb3cuZ2EgPSAod2luZG93LmdhID09PSB2b2lkIDApID8gbm9vcCA6IHdpbmRvdy5nYQogICAgaWYgKGRhdGFsYXllcikgewogICAgICAgIC8vIGV4ZWN1dGUgY2FsbGJhY2sgaWYgZXhpc3RzLCBzZWUgaHR0cHM6Ly93d3cuc2ltb2FoYXZhLmNvbS9ndG0tdGlwcy91c2UtZXZlbnR0aW1lb3V0LWV2ZW50Y2FsbGJhY2svCiAgICAgICAgaWYgKHR5cGVvZiBkYXRhbGF5ZXIucHVzaCA9PT0gJ2Z1bmN0aW9uJykgewogICAgICAgICAgICBkYXRhbGF5ZXIucHVz...RyeSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHNldFRpbWVvdXQob2JqLmV2ZW50Q2FsbGJhY2ssIHRpbWVvdXQpCiAgICAgICAgICAgICAgICAgICAgfSBjYXRjaChlcnJvcikge30KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAvLyBwcmV2ZW50IHBhZ2UgZGVsYXksIHNlZSBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9vcHRpbWl6ZQogICAgICAgIGlmIChkYXRhbGF5ZXIuaGlkZSAmJiBkYXRhbGF5ZXIuaGlkZS5lbmQpIHsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIGRhdGFsYXllci5oaWRlLmVuZCgpCiAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7fQogICAgICAgIH0KICAgIH0KfSkoKQ==' because it violates the following Content Security Policy directive: "script-src 'self' *.gravatar.com *.segment.io cdn.talkjs.com cdnjs.cloudflare.com *.calendly.com calendly.com p.typekit.net use.typekit.net maxcdn.bootstrapcdn.com *.paypalobjects.com *.paypal.com *.bluesnap.com songbirdstag.cardinalcommerce.com songbird.cardinalcommerce.com *.cardinalcommerce.com js.intercomcdn.com *.intercom.io *.auth0.com *.filestackapi.com *.fullstory.com fullstory.com js.hs-analytics.net js.hs-scripts.com js.hs-banner.com browser.sentry-cdn.com cdn.mxpnl.com snap.licdn.com assets.customer.io connect.facebook.net *.facebook.com *.googleapis.com *.googletagmanager.com *.googleadservices.com *.google-analytics.com *.gstatic.com *.googleusercontent.com *.google.com googleads.g.doubleclick.net tpc.googlesyndication.com securepubads.doubleclick.net 'unsafe-inline' 'unsafe-eval'". Note that 'script-src-elem' was not explicitly set, so 'script-src' is used as a fallback.
following https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/script-src#Unsafe_inline_script it should allow inline scripts.
What am i missing from my configuration ?
The express server side:
expressApp.use(helmet.contentSecurityPolicy({
directives: {
reportUri: '/report-csp-violation',
defaultSrc: ['*', 'data:', 'blob:'],
scriptSrc: [
'\'self\'',
...trustedDomains,
'\'unsafe-inline\'',
'\'unsafe-eval\'',
],
styleSrc: ['*', '\'unsafe-inline\'', 'data:'],
workerSrc: ['*', '\'unsafe-inline\'', 'data:', 'blob:'],
frameAncestors: ['\'none\''],
baseUri: ['\'self\''],
imgSrc: ['*', 'blob:', 'data:'],
},
}));
React app:
<Helmet>
<script async defer>
{googleTagManagerCode}
</script>
</Helmet>
The original CSP report sent by browser:
{
"document-uri": "https://app.....com",
"referrer": "",
"violated-directive": "script-src-elem",
"effective-directive": "script-src-elem",
"original-policy": "report-uri /report-csp-violation; default-src * data: blob:; script-src 'self' *.gravatar.com *.segment.io cdn.talkjs.com cdnjs.cloudflare.com *.calendly.com calendly.com p.typekit.net use.typekit.net maxcdn.bootstrapcdn.com *.paypalobjects.com *.paypal.com *.bluesnap.com songbirdstag.cardinalcommerce.com songbird.cardinalcommerce.com *.cardinalcommerce.com js.intercomcdn.com *.intercom.io *.auth0.com *.filestackapi.com *.fullstory.com fullstory.com js.hs-analytics.net js.hs-scripts.com js.hs-banner.com browser.sentry-cdn.com cdn.mxpnl.com snap.licdn.com assets.customer.io connect.facebook.net *.facebook.com *.googleapis.com *.googletagmanager.com *.googleadservices.com *.google-analytics.com *.gstatic.com *.googleusercontent.com *.google.com googleads.g.doubleclick.net tpc.googlesyndication.com securepubads.doubleclick.net 'unsafe-inline' 'unsafe-eval'; style-src * 'unsafe-inline' data:; worker-src * 'unsafe-inline' data: blob:; frame-ancestors 'none'; base-uri 'self'; img-src * blob: data:",
"disposition": "enforce",
"blocked-uri": "https://www.googletagmanager.com/gtm.js?id=....
"status-code": 0,
"script-sample": ""
}