Failing with CSP inside Intel XDK - html

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'">

Related

CSP behavior while sending Different CSP header value in different calls

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.

Unexpected blocked page when called from link in iframe to PDF file with chrome based browsers

I have a webpage in an iframe which contains a link to a foreign page with attributes target="_blank" rel="noopener". This link works well from the page itself and also from the iframe but only when called via context menu with the option open in new tab. A regular click opens a new tab and shows the correct URL but results in This page has been blocked by Opera ERR_BLOCKED_BY_CLIENT.
I looked around for help, disabled all addons to no avail and played the scenario in incognito mode as well, no change. The console on the error page shows VM589:1460 crbug/1173575, non-JS module files deprecated. This hint left me in the dark, however. I manipulated the attributes to target="_blank" rel="noopener" rel="noreferrer" or rel="noopener noreferrer" with no success. This all applies to Opera.
I tried Brave with the same result and error message, except Brave instead of Opera, of course. Edge joins the failure band. No surprise then to see This page has been blocked by Chrome proper as well.
This error applies to all PDF-file links from the iframe, normal external links work well. Firefox shows briefly PDF.js viewer in the new tab and then works normal. I had no chance to try links to YouTube or the like, but I guess there is ample evidence I hit a bug in the chrome PDF-rendering engine.
What to do? Who is interested in this bug and how to reach them? Or is there anything I can do in my code?
Browser use already longer time the Content Security Policy (CSP) to protect users from undesired content. The definition of undesired content can be made by the site owner. if the site owner hasn't done that, then some standard values are used, which are more restrictive.
The website https://content-security-policy.com/ explains it like this
What is Content-Security-Policy?
Content-Security-Policy is the name of a HTTP response header that modern browsers use to enhance the security of the document (or web page). The Content-Security-Policy header allows you to restrict how resources such as JavaScript, CSS, or pretty much anything that the browser loads.
Although it is primarily used as a HTTP response header, you can also apply it via a meta tag.
The term Content Security Policy is often abbreviated as CSP.
What types of attacks does Content-Security-Policy help mitigate?
CSP was first designed to reduce the attack surface of Cross Site Scripting (XSS) attacks, later versions of the spec also protect against other forms of attack such as Click Jacking.
In your case you have to configure two hurdles for the user:
The iframe, required rule:
frame-src 'self'
The PDF, required rule:
object-src 'self' blob;
Essentially it's relatively safe to allow most things with 'self' but it's always good to disallow elements that are not used at all on the site.
Your Content Security Policy should look similar to this, and should allow PDFs in iframes:
Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; object-src 'self' blob:; style-src 'self'; frame-src 'self';
The best is to configure the CSP in the server configuration. This is not possible for every site owner though, and it's possible to configure the CSP in meta tags too. You could add this to your site inside the head-tag:
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; object-src 'self' blob:; style-src 'self'; frame-src 'self'">
Setting the CSP in the server configuration is the stronger approach though:
https://content-security-policy.com/examples/meta/
Here are more examples, including CSP related server configuration for Apache Web Server and Nginx Webserver:
https://content-security-policy.com/examples/
EDIT
If the PDF is hosted on another domain, then the CSP has to adjusted differently, more openly.
Different options for sources are explained here:
https://content-security-policy.com/#source_list
The iframe, required rule has to be adjusted.
It should be restricted either to a special domain with *.example.com or to a nonce with 'nonce-rAnd0m'.
The PDF, required rule has to be adjusted, the same advise like for point 1. is applying.
So even the PDF is external then, it doesn't mean that everything could be injected somehow in the website.
Assumed you use the option with the domain *.example.com it would look like or similar to this then:
Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; object-src '*.example.com' blob:; style-src 'self'; frame-src '*.example.com'
Assumed you use the option with the nonce it would look like or similar to this then:
Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; object-src 'nonce-rAnd0m' blob:; style-src 'self'; frame-src 'nonce-rAnd0m'
I didn't test it, so slight adjustments might be required.

Loading image SVG and getting Content Security Policy (CSP) error

I'm trying to load SVG images and get a CSP error as follows:
I keep getting the error event when I added the meta tag:
<meta http-equiv="Content-Security-Policy" content="default-src *;img-src * 'self' data: https:; script-src 'self' 'unsafe-inline' 'unsafe-eval' *; style-src 'self' 'unsafe-inline' *" >
The error that you can see tells you that the img-src was not set and it fallbacks to default-src even though that you have added meta tag with your CSP values.
This behaviour can be observed when the CSP header is already set via HTTP. You have to choose whether to set it via HTTP or as meta tag.

Adding google fonts (fonts.googleapis.com) to CSP header

I am hosting a personal project on gitHub pages, and using cloudflare to enforce https. Now I would like to implement a CSP policy.
I tried adding meta tag to the head of my page:
<meta HTTP-EQUIV='Content-Security-Policy' CONTENT="default-src 'self' *.fonts.googleapis.com/* *.cloudflare.com/* *.fonts.googleapis.com/*;">
But I am getting the following error:
Refused to load the stylesheet
'https://fonts.googleapis.com/icon?family=Material+Icons' because it
violates the following Content Security Policy directive: "default-src
'self' .fonts.googleapis.com/ .cloudflare.com/
.fonts.googleapis.com/". Note that 'style-src' was not explicitly set, so 'default-src' is used as a fallback.
This are the scripts that I am including:
<link href="https://fonts.googleapis.com/icon?family=Material+Icons"
rel="stylesheet">
<link href="https://fonts.googleapis.com/css?family=Noto+Sans|Roboto" rel="stylesheet">
won't setting *.fonts.googleapis.com/* allow everything from the page?
Since this is the first time I am setting a CSP is this the correct way to set it for github pages? I have not found any reading on this yet.
Won't setting *.fonts.googleapis.com/* allow everything from the page?
Although this would be intuitive, the answer is no.
See the pretty good HTML5rocks introduction to Content Security Policy on the topic of wildcards (section Implementation details):
Wildcards are accepted, but only as a scheme, a port, or in the leftmost position of the hostname: *://*.example.com:* would match all subdomains of example.com (but not example.com itself), using any scheme, on any port.
So a working CSP for the two fonts could look something like this:
<meta http-equiv="Content-Security-Policy" content="default-src 'self' https://fonts.googleapis.com/ https://fonts.gstatic.com/ 'unsafe-inline';">
Note 1: It's a good practice to use the corresponding CSP directives. In your case you should use the font-src and style-src like so:
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; font-src 'self' https://fonts.gstatic.com/; style-src 'self' https://fonts.googleapis.com/ 'unsafe-inline';">
The advantage of using the corresponding directives is that your CSP gets pretty restrictive now. E.g., you're not allowing 'unsafe-inline' for script sources anymore. This means inline javascript is now forbidden. It's also forbidden to load scripts from https://fonts.gstatic.com/, which was allowed before. And so on...
Note 2: You can get rid of the 'unsafe-inline' keyword at all by using a hash or a nonce. I have not been able to make this work for this example but if you're interested, just take a look at the HTML5rocks intro again.

Compromised Chrome? Modified Content-Security-Policy

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.