I am using helmet to set CSP headers. I am using React on the frontend.
I store my images on a subdomain (assets.mydomain.com). For some reason I get the following error message: ERR_BLOCKED_BY_RESPONSE.NotSameOriginAfterDefaultedToSameOriginByCoep when loading the images.
I also use a script tag for Google Analytics. This one also gives me an error message: Refused to connect to https://www.google-analytics.com/ because it violates... "default-src 'self'"
This is how I have configured my CSP currently:
app.use(
helmet({
contentSecurityPolicy: {
directives: {
defaultSrc: ["'self'"],
scriptSrc: [
"'self'",
"https://www.googletagmanager.com",
"'self'",
"https://www.google-analytics.com",
"'unsafe-inline'",
"mydomain.com",
],
imgSrc: ["'self'", "assets.mydomain.com"],
},
},
crossOriginEmbedderPolicy: false,
crossOriginResourcePolicy: false,
})
);
What is wrong with my CSP configuration?
So if anyone comes across this question for some reason, I figured it out. As it turns out, the cross-origin-embedder-policy header was giving me troubles. This had to be disabled. Helmet has a built in option to do so crossOriginEmbedderPolicy: false,. More info here.
For most people I guess that'll work. However it did not work for me. The header was still being set. Disabling it with express also did not work (app.disable('cross-origin-embedder-policy');).
I have no idea why the header was still being set, but I had to disable it manually in my nginx configuration: proxy_hide_header cross-origin-embedder-policy;
My config:
app.use(
helmet({
contentSecurityPolicy: {
directives: {
defaultSrc: ["'self'"],
scriptSrc: [
"'self'",
"'unsafe-inline'",
"https://*.google.com",
"https://*.google-analytics.com",
"https://*.googletagmanager.com",
"https://*.hotjar.com",
"https://*.mollie.com",
],
connectSrc: [
"'self'",
"'unsafe-inline'",
"https://*.google.com",
"https://*.google-analytics.com",
"https://*.googletagmanager.com",
"https://*.hotjar.com",
"https://*.mollie.com",
],
imgSrc: [
`'self'`,
`data:`,
`*.domain.nl`,
`*.amazonaws.com`,
],
},
},
//Will work for most, but did not work for me:
// crossOriginEmbedderPolicy: false,
})
);
//# in nginx I manually disabled the COEP header: roxy_hide_header cross-origin-embedder-policy;
I did it!!!
After literally hundreds of test-error I found that this little piece of code at least, it fixed my problem of having 2 different services (2 domains) and now my little app is working fine again, time 1:11am !! :)
app.use(
helmet({
contentSecurityPolicy: {
directives: {
scriptSrc: ["'self'", 'www.google.com www.gstatic.com',"https://*.statcounter.com", "'unsafe-inline'"],
frameSrc: ["'self'", "www.google.com", "https://*.statcounter.com"],
connectSrc: ["'self'", 'https://*.statcounter.com'],
},
},
crossOriginResourcePolicy: { policy: "cross-origin" },
crossOriginEmbedderPolicy: false,
})
);
Related
currently I'm uploading something file. Succeed when uploading the file to Google Cloud Storage, but when get the file, I have getting error something like this
If I check and see detail, the source is wrong, for example, the correct link should be like this https://storage.cloud.google.com/cms-strapi-storage/thumbnail_cloudsql_ae61374abd/thumbnail_cloudsql_ae61374abd.png
Anyone can help me? Thank you
My reference and package got from this source : https://www.npmjs.com/package/strapi-provider-upload-google-cloud-storage#setup-auth
The issue already solved!
The way to solve that issue is
Cause the env is production mode, in Strapi v4, you should create everything files into config/env/production
Create file plugins.js, fill it like this.
const fs = require('fs');
require('dotenv').config();
module.exports = ({ env }) => ({
upload: {
config: {
provider: 'strapi-provider-upload-google-cloud-storage',
providerOptions: {
serviceAccount: JSON.parse(fs.readFileSync(process.env.GCS_SERVICE_ACCOUNT)),
bucketName: env('GCS_BUCKET_NAME'),
basePath: env('GCS_BASE_PATH'),
baseUrl: env('GCS_BASE_URL'),
publicFiles: true,
uniform: false,
gzip: true,
},
},
},
});
The key is publicFiles, because if value is false it doesn't create public url in Google Cloud Storage and we cannot get and see the image
Addition notes, don't forget to add security in order to get permission from GCS (Google Cloud Storage)
module.exports = [
'strapi::errors',
{
name: 'strapi::security',
config: {
contentSecurityPolicy: {
useDefaults: true,
directives: {
'connect-src': ["'self'", 'https:'],
'img-src': ["'self'", 'data:', 'blob:', 'storage.googleapis.com'],
'media-src': ["'self'", 'data:', 'blob:', 'storage.googleapis.com'],
upgradeInsecureRequests: null,
},
},
},
},
'strapi::cors',
'strapi::poweredBy',
'strapi::logger',
'strapi::query',
'strapi::body',
'strapi::favicon',
'strapi::public',
];
I implemented adsense, but I have the following error message printed in the console when loading a webpage with ads on. Thing is it loads this error message sometimes, not every time I reload the same page.
Refused to frame 'https://pagead2.googlesyndication.com/' because it
violates the following Content Security Policy directive: "frame-src
cm.g.doubleclick.net googleads.g.doubleclick.net www.google.com
accounts.google.com
pagead2.googlesyndication.com/pagead/s/cookie_push.html gmsg:
https://tpc.googlesyndication.com/sadbundle/..."
I have the following CSP policies set on my Node server :
app.use(
helmet.contentSecurityPolicy({
useDefaults: true,
directives: {
defaultSrc: ["'self'"],
scriptSrc: [
"'self'",
'googleapis.com',
],
objectSrc: ["'none'"],
frameSrc: [
"'self'",
'https://pagead2.googlesyndication.com/',
'cm.g.doubleclick.net',
'googleads.g.doubleclick.net',
'www.google.com',
'accounts.google.com',
'https://adservice.google.com/',
'https://tpc.googlesyndication.com/',
],
},
})
);
Any idea what I am missing ?
I am serving a react app build using express.
const root = path.join(__dirname, 'build/');
app.use(express.static(root));
app.use((req, res, next) => {
if (req.method === 'GET' && req.accepts('html') && !req.is('json') && !req.path.includes('.')) {
res.sendFile('index.html', { root });
} else next();
});
Everything works as intended. However as soon as i add helmet (NOT react-helmet) to the express app, I get issues (styles and scripts didn't load).
After searching several resources I was able to come up with a solution to make it work.
The below code shows the fix i did to make the styles and scripts load.
app.use(helmet());
app.use(helmet.contentSecurityPolicy({
defaultSrc: [
'\'self\'',
'https://api.domain.tld/*',
'https://domain.tld',
],
styleSrc: [
'\'self\'',
'\'unsafe-inline\'',
'https://*.googleapis.com',
'https://api.domain.tld/*',
'https://domain.tld',
],
scriptSrc: [
'\'self\'',
'\'unsafe-inline\'',
'https://api.domain.tld/*',
'https://domain.tld',
],
contentSrc: [
'\'self\'',
'\'unsafe-inline\'',
'https://api.domain.tld/*',
'https://domain.tld',
],
}));
Additionally I also included INLINE_RUNTIME_CHUNK=false in the .env file.
The issue I have currently is that the API calls I am making to api.domain.tld does not work. It gets blocked and the following errors show up on firefox.
Content Security Policy: The page’s settings blocked the loading of a resource at https://api.domain.tld/endpoint (“default-src”).
Chrome shows the following error.
Refused to connect to 'https://api.domain.tld/endpoint' because it violates the following Content Security Policy directive: "default-src 'self'". Note that 'connect-src' was not explicitly set, so 'default-src' is used as a fallback.
Please note that the react app is on domain.tld and the API is on api.domain.tld
How can if fix this issue so I can make API calls?
There is 2 issues:
Do fix a syntax error: contentSrc: -> connectSrc:
CSP spec does not allow using * (wildcard) in the path-part, therefore do fix 'https://api.domain.tld/* -> 'https://api.domain.tld/'. Also in the path-part you can use:
a folder name: 'https://api.domain.tld/real_path_here/' (with trailing slash /) - will allow any subfolders and any files in specified folder and subs.
file name: 'https://api.domain.tld/endpoint' or 'https://api.domain.tld/some_path/script.js' (without trailing slash /) - will allow specified file_name only.
According to the Documentation, You should specify sources inside the directives
app.use(helmet.contentSecurityPolicy({
useDefaults: false, // you can change it to `true` if you want.
directives:{
defaultSrc: [
'\'self\'',
'https://api.domain.tld/',
'https://domain.tld',
],
styleSrc: [
'\'self\'',
'\'unsafe-inline\'',
'https://*.googleapis.com',
'https://api.domain.tld/',
'https://domain.tld',
],
'image-src': [
'\'self\'',
'\'unsafe-inline\'',
'data:',
'https://api.domain.tld/',
'https://domain.tld',
],
scriptSrc: [
'\'self\'',
'\'unsafe-inline\'',
'https://api.domain.tld/*',
'https://domain.tld',
],
contentSrc: [
'\'self\'',
'\'unsafe-inline\'',
'https://api.domain.tld/',
'https://domain.tld',
],
}
}));
Update
To fix the image not loading issue, Add the following.
imageSrc: [
'\'self\'',
'\'unsafe-inline\'',
'data:',
'https://api.domain.tld/',
'https://domain.tld',
],
We are trying to implement Content security policy in our web application. Our application stack is MERN.Using helmet package we are trying to implement Content security policy in node js .
Currently We have enabled reportOnly mode in production for testing purpose and facing this error only in our production not in development or staging environments. Effective-attribute is script-src-elem and user agent is Window 10 chrome user-agent. We are confused how to proceed with this error as it impacting on our own script and some other valid sources randomly.We are confused whether to enforce CSP in production or not?
I'm facing a issue. script-src-elem is blocked although defined in script-src.
I am using node js . Using helmet package,we have configured csp.my csp list for reference is -
app.use(
helmet.contentSecurityPolicy({
reportOnly: true,
setAllHeaders: false,
directives: {
defaultSrc: ['*', 'data:', 'ws:'],
imgSrc: [
'*.sample.com',
'https:',
'blob:',
'data:' ],
styleSrc: [
"'self'",
"'unsafe-inline'",
'assets.sample.com',
'https://fonts.googleapis.com',
'https://accounts.google.com',
'data:',
'blob:',
],
scriptSrc: [
"'self'",
"'unsafe-inline'",
"'unsafe-eval'",
'data:',
'blob:',
'https://*.sample.com',
'https://*.google-analytics.com',
'https://*.facebook.net',
'https://*.google.com',
],
],
frameAncestors: ["'self'"],
workerSrc: ["'self'", 'blob:'],
objectSrc: ["'none'"],
reportUri: '/violation',
},
}),
);
I'm facing csp violation under script-src-elem for url https://assets.sample.com/build/resultpage.9cff494c01ced7b4.chunk.js , https://connect.facebook.net. I am not aware what mistake has been commited in the configuration. Can somenone help us out!!! Thanks in advance.
I am not sure if you have defined your strings correctly. You are giving the protocol prefix of the url in the string and I believe that isn't correct. Entries like
scriptSrc: [
"'self'",
"'unsafe-inline'",
"'unsafe-eval'",
'data:',
'blob:',
'https://*.sample.com',
'https://*.google-analytics.com',
'https://*.facebook.net',
'https://*.google.com',
],
should probably be
scriptSrc: [
"'self'",
"'unsafe-inline'",
"'unsafe-eval'",
'data:',
'blob:',
'*.sample.com',
'*.google-analytics.com',
'*.facebook.net',
'*.google.com',
],
Try that and see if it helps
I am trying to add a paypal button, but the image doesnt load and gives the below error
Content Security Policy: The page’s settings blocked the loading of a resource at data:image/svg+xml;base64,PHN2ZyB3aWR0aD… (“default-src”)
Below is my meta code
<meta http-equiv="Content-Security-Policy" content="default-src * 'data'; img-src: *; style-src 'self' 'unsafe-inline' https://* http://*; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://* http://*" />
I have many external scripts/css/images which are loaded and i want allow everything to load without getting blocked.
Any help will be appreciated
You have defined img-src with just * which will include everything HTTP or HTTPS depending on your connection. 'data' will not be included. You will need to include data: (with the colon but without quotes) to img-src. You have included 'data' in default-src, but as you have defined img-src this fallback will not be used. Also check your syntax as pointed out by #sideshowbarker.
I recommend you to use helmet library instead of hard-coding security headers in your head tag even if having master pages. After that you can check if your headers are now secured on https://securityheaders.com/.
In case of nodejs my implementation looks like following:
const helmet = require('helmet');
app.use(
helmet.contentSecurityPolicy({
useDefaults: false,
"block-all-mixed-content": true,
"upgrade-insecure-requests": true,
directives: {
"default-src": [
"'self'"
],
"base-uri": "'self'",
"font-src": [
"'self'",
"https:",
"data:"
],
"frame-ancestors": [
"'self'"
],
"img-src": [
"'self'",
"data:"
],
"object-src": [
"'none'"
],
"script-src": [
"'self'",
"https://cdnjs.cloudflare.com"
],
"script-src-attr": "'none'",
"style-src": [
"'self'",
"https://cdnjs.cloudflare.com",
"https://fonts.googleapis.com"
],
},
}),
helmet.dnsPrefetchControl({
allow: true
}),
helmet.frameguard({
action: "deny"
}),
helmet.hidePoweredBy(),
helmet.hsts({
maxAge: 123456,
includeSubDomains: false
}),
helmet.ieNoOpen(),
helmet.noSniff(),
helmet.referrerPolicy({
policy: [ "origin", "unsafe-url" ]
}),
helmet.xssFilter()
);
More info about these filters can be found on https://helmetjs.github.io/