My application is being reverse proxied by Nginx.
I've setup Nginx to add a Content-Security-Policy header to the response. This is working perfectly and I can see the header returned from Chrome as well as CURL from a number of machines.
From a particular machine I'm seeing something very strange. Chrome is showing only a small portion of the Content-Security-Policy header was returned in the response, leaving out a number of key policies. When using a different browser on the same machine the headers are all returned.
Apologies if this is a silly question but could it be that a binary or something else in Chrome has been modified and is modifying the Content-Security-Policy header? I understand how ridiculous that sounds and there could be something I don't understand about CSP.
Could someone help me understand what is happening here?
What most machines are getting:
Content-Security-Policy:default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://ssl.google-analytics.com https://assets.zendesk.com https://connect.facebook.net; img-src 'self' https://ssl.google-analytics.com https://s-static.ak.facebook.com https://assets.zendesk.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com https://assets.zendesk.com; font-src 'self' https://themes.googleusercontent.com; frame-src https://assets.zendesk.com https://www.facebook.com https://s-static.ak.facebook.com https://tautt.zendesk.com; object-src 'self'
What this one particular machine is getting:
Content-Security-Policy:default-src 'self';
Eureka! I have the answer.
It looks like ESET was inspecting and modifying the headers in the request. You can switch this off quite easily.
Related
I want to understand how the CSP will be applied when different REST responses in the page have different header value for CSP. We dont have any meta tag for CSP. CSP is applied only through response headers.
Lets take the scenarios of 3 APIs
GET /api/v1/users - Content-Security-Policy: default-src 'self' google.com; script-src 'self' 'unsafe-inline' 'unsafe-eval' google.com
GET /api/v1/roles - Content-Security-Policy: default-src 'self'; script-src 'self'; img-src 'self'
GET /api/v1/permission - Content-Security-Policy: default-src 'self' google.com; script-src 'self' 'unsafe-inline' 'unsafe-eval' google.com
In this case, what will be the CSP considered by the browser for subsequent requests?
Also, in my understanding, server sets the CSP in the response header to inform browser about what content will be allowed going forward. is that correct?
A CSP determines what resources can be loaded on a page and is only applied on pages that are rendered in the browser, typically with content type "text/html". So there is no benefit in setting it on images, scripts, styles etc.
The CSP that makes sense for an API is frame-ancestors 'none', see https://cheatsheetseries.owasp.org/cheatsheets/REST_Security_Cheat_Sheet.html#security-headers for an explanation.
I'm trying to do a porting of an Chrome Extension to use it on Firefox.
The extension just display some informations about the Jira ticket in Github website. In Chrome it looks like:
Everything works well after change few things, except loading images from Atlassian (Jira) website.
Due to some CSP block:
Content Security Policy: The page's settings blocked the loading of a resource at https://myproject.atlassian.net/images/icons/statuses/generic.png ("img-src").
What I don't understand, is that Content-Security-Policy: img-src is supported by both Chrome & Firefox since almost 10 years. So why do they act different?
The content-security-policy header contains for img-src:
img-src
'self'
data:
github.githubassets.com
identicons.github.com
github-cloud.s3.amazonaws.com
secured-user-images.githubusercontent.com/
github-production-user-asset-6210df.s3.amazonaws.com
*.githubusercontent.com;
Full policy:
default-src 'none'; base-uri 'self'; block-all-mixed-content; child-src github.com/assets-cdn/worker/ gist.github.com/assets-cdn/worker/; connect-src 'self' uploads.github.com objects-origin.githubusercontent.com www.githubstatus.com collector.github.com raw.githubusercontent.com api.github.com github-cloud.s3.amazonaws.com github-production-repository-file-5c1aeb.s3.amazonaws.com github-production-upload-manifest-file-7fdce7.s3.amazonaws.com github-production-user-asset-6210df.s3.amazonaws.com cdn.optimize…ithubusercontent.com notebooks.githubusercontent.com; img-src 'self' data: github.githubassets.com identicons.github.com github-cloud.s3.amazonaws.com secured-user-images.githubusercontent.com/ github-production-user-asset-6210df.s3.amazonaws.com *.githubusercontent.com; manifest-src 'self'; media-src github.com user-images.githubusercontent.com/; script-src github.githubassets.com; style-src 'unsafe-inline' github.githubassets.com; worker-src github.com/assets-cdn/worker/ gist.github.com/assets-cdn/worker/
So I understand why Firefox refuse to load it. But why Chrome do it without any problem?
I'm trying to setup CSP headers for my application. I have intentionally left out our CDN from font-src
and style-src directives so that violation is triggered. I can see the violations on the Chrome Dev Tools console but the request to the csp-endpoint specified in the header is not triggered. I have tried by setting the report-uri attribute but that didn't help either. I'm testing this on Chrome 84 which is supposed to support report-to directive. Is there anything I'm missing here?
Content-Security-Policy-Report-Only: default-src 'none'; script-src 'self' 'unsafe-inline' 'unsafe-eval' www.googletagmanager.com www.google-analytics.com; style-src 'self' data: 'unsafe-inline' www.tagmanager.google.com www.fonts.googleapis.com fast.fonts.net; img-src 'self' data: www.googletagmanager.com www.google-analytics.com; form-action 'self'; font-src 'self'; connect-src 'self'; report-to csp-endpoint
Report-To: {"endpoints":[{"url":"http://localhost:8080/myapp/csp-violation-report"}],"group":"csp-endpoint","max_age":10886400}
report-to endpoints should have a secure context (actually - https:). Non-secure endpoints will be ignored.
There is some problems with resolving of localhost name, not all user agents treat it as trustworthy. The localhost should conforms to the specific (para 5) name resolution rules (pls see Let 'localhost' be localhost RFC update).
Briefly - try to use https://127.0.0.1:8080/myapp/csp-violation-report. May be a secure https: https://localhost:8080/myapp/csp-violation-report will be enough for Chrome (Chrome 84 supports the report-to directive, but Firefox - does not).
I am adding Security Headers to my website. I am running an Nginx server.
I have used the "Content Security Policy (CSP) Generator" chrome extension to create my CSP settings.
The CSP statement added to nginx ssl.conf are:
add_header Content-Security-Policy "default-src 'self';
script-src 'report-sample' 'self' https://maps.googleapis.com/.../util.js;
style-src 'report-sample' 'self' https://code.jquery.com https://fonts.googleapis.com;
object-src 'none';
base-uri 'self';
connect-src 'self';
font-src 'self' https://fonts.gstatic.com;
frame-src 'self';
img-src 'self' data: https://code.jquery.com https://maps.gstatic.com;
manifest-src 'self';
media-src 'self';
report-uri https://???.endpoint.csper.io/;
worker-src 'none';";
The only browser these settings seems to work in is Firefox.
When I load the site in Chrome (v77.01) the site does not load. It shows the same result in Edge (Version 83.0.478.54), Safari and Opera.
I see the following info:
This site can’t be reached The webpage at https:domain.com might be temporarily down or it may have moved permanently to a new web address. ERR_HTTP2_PROTOCOL_ERROR
The ssl certificate is Lets Encrypt and is set to expire in Sept 2020.
Any advice would be greatly appreciated.
Cheers
Greg J
ok this has been fixed and as usual its really basic, feeling a bit of a douche...
Chrome browser does not like linefeeds in the CSP statement. once I made the statement a single line it worked perfectly.
Okay so I have this web api with different endpoints to call different json values for instance:
https://example.com/api/values
https://example.com/api/othervalues
I only add the uri https://example.com/api/ in the network request within cordova whitelist and it works good and can call from both endpoints.
However
When trying to do the same thing with CSP (http://www.html5rocks.com/en/tutorials/security/content-security-policy/#reporting) (https://software.intel.com/en-us/articles/cordova-whitelisting-with-intel-xdk-for-ajax-and-launching-external-apps) it just won't work when build or app preview(iOS) but it works inside the emulator.
This is the code I'm using that fails but works in emulator on the computer
<meta http-equiv="Content-Security-Policy" content="default-src 'self' https://example.com/api/valuest/; img-src 'self' https://example.com/api/othervalues; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com/; script-src 'self' 'unsafe-inline'">
And this one works everywhere, aka build, emulator, app preview
<meta http-equiv="Content-Security-Policy" content="default-src 'self' * https://example.com/api/valuest/; img-src 'self' https://example.com/api/othervalues; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com/; script-src 'self' 'unsafe-inline'">
Look for the * inside the default src, that's the only difference, so obviously there's something that is not being allowed running in the first <meta> tag but I fail to find out what. I've literally tried every other resource directive and the only one working is adding the * inside the default src.
Now
I'm now considering just going with the cordova whitelist and skip the Content Security Policy. I don't know much about security but.. might not this be enough? The app will only be able to run on mobile devices(not a computer app) which should make it harder to attack I guess? And from my understanding reading from this link(http://www.html5rocks.com/en/tutorials/security/content-security-policy/#inline-code-considered-harmful ), using CSP is pretty much only better if I deny inline scripts, otherwise it serves the same purpose like the cordova whitelist?
If anyone has any input or advice about this I'd highly appreciate your help, Thanks!
I tried to edit your code samples to make them more readable.
My guess is that you have to specifiy the URL of your web service like so:
<meta http-equiv="Content-Security-Policy" content="default-src 'self' https://example.com/; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com/; script-src 'self' 'unsafe-inline'">
You don't have to specify the exact URL of your service, but the URL of the source you trust. Note aswell that if you set https://example.com/as default-src there is no need to set it as img-src, as the default-src will override any other directive that is not set specifically...
"Further reading":
For me it was even possible to set the URL of used web services as a connect-src, which is more restrictive (and therefore provides better protection). Of course this depends on how you're interacting with the server, the html5rocks article you mentioned is quite a good source to figure out what you might want to use... Anyway a possible meta tag using the connect-src could look something like this:
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; connect-src 'self' https://example.com/; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com/; script-src 'self' 'unsafe-inline'">