Is this method of applying content security policy ok? - html

I am trying to add CSP to my web application, I have added the following meta tag in my index page:
<meta http-equiv="Content-Security-Policy" content="img-src 'self' data:;default-src *;style-src 'self' http://* 'unsafe-inline';script-src 'self' http://* 'unsafe-inline' 'unsafe-eval';" />
and Also the following my my web.config file on IIS:
<customHeaders>
<add name="Content-Security-Policy" value="default-src 'self' 'unsafe-inline' http://*.domain.com;
img-src 'self' http://*.domain.com data:" />
</customHeaders>
Is it necessary to add both meta tag and additional headers? or One of them is sufficient?
Does the meta tag policy override the custom header?
Does this script-src 'self' http://* 'unsafe-inline' 'unsafe-eval' mean that I can write inline JavaScript and use eval function inside my code? Does this rule override the policy set by headers? (because as far as I know in headers I have prohibited usage of inline JavaScript and eval function)
And my last question is if I use these settings, Should I use ng-csp or its other variant ng-csp="no-unsafe-eval" in my html?

Is it necessary to add both meta tag and additional headers? or One of them is sufficient?
One is sufficient. If you can make your server send the policy in a response header, that’s better. You don’t need to also specify anything in a meta element too, and there’s no advantage to it.
Does the meta tag policy override the custom header?
The meta policy will only override the header policy if the meta policy is stricter. See this answer:
What is happening when I have two CSP (Content Security Policies) policies - header & meta?
… which cites a part of the CSP that says, “adding additional policies to the list of policies to enforce can only further restrict the capabilities of the protected resource”.
Does this script-src 'self' http://* 'unsafe-inline' 'unsafe-eval' mean that I can write inline JavaScript and use eval function inside my code?
It would do that if your header also specified those values for script-src. But your header policy does not. So the browser uses the strictest policy, regardless of where it’s specified.
Does this rule override the policy set by headers? (because as far as I know in headers I have prohibited usage of inline JavaScript and eval function)
No, as the What is happening when I have two CSP (Content Security Policies) policies - header & meta? answer explains, you can’t override a strict policy by specifying a less-strict policy elsewhere.
So you’re best off specifying all your policy values in just one place, in a header (instead of meta).

Related

Add unpkg to Content Security Policy (CSP)

How can I add specific libraries (ES modules) fetched through Unpkg to my Content Security Policy (CSP) policy - i.e. without allowing everything from Unpkg?
For example, this is how I add provide one library:
<script
type="module"
src="https://unpkg.com/web-social-share#latest/dist/websocialshare/websocialshare.esm.js"></script>
I tried various solution such as https://unpkg.com/web-social-share#latest/* or https://unpkg.com/web-social-share#* for my script-src policy but all resulted in an error:
Refused to load the script 'https://unpkg.com/web-social-share#latest/dist/websocialshare/websocialshare.esm.js' because it violates the following Content Security Policy directive: "script-src 'self' ...
Anything that seems to work is allowing everything from Unpkg which I would like to avoid.
<meta
http-equiv="Content-Security-Policy"
content="default-src 'self';
script-src 'self' https://unpkg.com/;" />
This is available only in CSP level 3: https://www.w3.org/TR/CSP3/#external-hash. But unfortunately you'll still need to support level 2. You can however use Subresource Integrity in most browsers.

Why is my Content Security Policy not being adhered to?

I've come a cross a very bizarre situation where a hash is being ignored, despite it being present in the Content-Security-Policy.
This happened while installing Hotjar on our website, manually adding hashes for every inline script it uses, but obviously it can presumably happen with any dynamically inserted inline script.
In the console error message below you can see that the required hash is present, but Chrome suggests that it needs to be added...
Refused to apply inline style because it violates the following Content Security Policy directive: "style-src 'nonce-llX8ZkdD3suoiNrpE9mCatplNhRYmlKw' 'self' 'sha256-HRecKxp1fRukFUlrmQh3cAVyb/pNYtdWFGJ2EL5FzdE=' 'sha256-SvLgADqEePEV9RNxBrRQXSBJafFHcVNG7cPzHz6h9eA=' 'sha256-fGP7dUodgG1o2qqo7hPGqd+2FEE7z2Z4Xg5muj+XIOQ=' 'sha256-8hoDThJonkR/uDTFl5y8ugf9U3kcHPL2sq19iPFHTds=' 'sha256-ecMh1s2mivgxX0zzJbkamgAS7kPx+1EqcHz8Uz30i78=' 'sha256-Qv05/NsT/MWFR5NB3hDHRW9iI424uc8WpuRssGdOAsU=' 'sha256-47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=' 'sha256-S3EaMUkdpUGJFgSHH5d/29s3oD8/sutxvMfQoprfQ+g=' 'sha256-qVlOiWrAwuIfu8+uHKHkgg4qBA7YOoSm8A0yB4LfrNw=' *.hotjar.com *.typekit.net".
But the remedy is to include a hash that's already present:
Either the 'unsafe-inline' keyword, a hash ('sha256-S3EaMUkdpUGJFgSHH5d/29s3oD8/sutxvMfQoprfQ+g='), or a nonce ('nonce-...') is required to enable inline execution.
The hashes in CSP and proposed solution are identical:
And here is the complete CSP:
Content-Security-Policy: default-src *; base-uri 'self'; img-src * data:; style-src 'nonce-{$nonce}' 'self' 'sha256-HRecKxp1fRukFUlrmQh3cAVyb/pNYtdWFGJ2EL5FzdE=' 'sha256-SvLgADqEePEV9RNxBrRQXSBJafFHcVNG7cPzHz6h9eA=' 'sha256-fGP7dUodgG1o2qqo7hPGqd+2FEE7z2Z4Xg5muj+XIOQ=' 'sha256-8hoDThJonkR/uDTFl5y8ugf9U3kcHPL2sq19iPFHTds=' 'sha256-ecMh1s2mivgxX0zzJbkamgAS7kPx+1EqcHz8Uz30i78=' 'sha256-Qv05/NsT/MWFR5NB3hDHRW9iI424uc8WpuRssGdOAsU=' 'sha256-47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=' 'sha256-S3EaMUkdpUGJFgSHH5d/29s3oD8/sutxvMfQoprfQ+g=' 'sha256-qVlOiWrAwuIfu8+uHKHkgg4qBA7YOoSm8A0yB4LfrNw=' *.hotjar.com *.typekit.net; script-src 'nonce-{$nonce}' 'self' 'sha256-A0/707MQdpfr/tR18VnYSk7JMJoUQSBURZEJa8wF6po=' 'sha256-1kpOd8fXCkigqXNekDPt+noalDB6YI+94YhtU3ETmvE=' *.hotjar.com *.googletagmanager.com *.universe.com *.google-analytics.com *.quantserve.com *.quantcount.com *.ads-twitter.com *.facebook.net analytics.twitter.com *.stripe.com polyfill.io *.queue-it.net *.amplitude.com; object-src 'none'; frame-ancestors 'self' *.queue-it.net
To replicate this all you'd have to do is install Hotjar with the above CSP.
Is this a Chrome bug or have I missed something?
Here's a screenshot for anyone interested (click to zoom in).
This issue is the same as CSP header fails with "Refused to apply inline style..." but I have already added the hash.
You have either an:
inline event handler in the tag like onclick='javascript_here', onload='js_handler()' etc.
OR
javascript-navigation like <a href='javascript:...'
Chrome calculates hashes for those but to allow this kind of inline script you need to also add unsafe-hashes token to the 'script-src'.
Note: Safari 12 does not support 'unsafe-hashes', therefore may be better to hang event handlers with addEventListener() in case of 1.

how to set multiple Content Security Policies in a chrome extension manifest.json file

in the Google chrome documentation I found that I can add content Security Policy to allow an external javascript file to work on my extension.
but I couldn't find how to add multiple ones. Is it an array of Strings?
"content_security_policy": "script-src 'self' https://example.com; object-src 'self'"
I tried to put multiple lines like that but it doesn't work. Goes error:
Refused to load the script https://example.com because it violates the following Content Security Policy directive: "script-src 'self' https://example.com". Note that 'script-src-elem' was not explicitly set, so 'script-src' is used as a fallback.
CSP policy is a single string (containing a semicolon-separated list of directives and their arguments). It applies to all extension pages.
If you need a single policy with multiple sources, you can do that. In fact, you already have that: 'self' and https://example.com are two sources.
Read about CSP in general and script-src directive, e.g. on the MDN.
Syntax
One or more sources can be allowed for the script-src policy:
Content-Security-Policy: script-src <source>;
Content-Security-Policy: script-src <source> <source>;
So you just need to space-separate them between script-src and the semicolon.
Make sure that your sources do not contain paths.
E.g. https://example.com is OK, but https://example.com/ or https://example.com/script.js are not.
If you need multiple independent policies for different pages, I'm afraid you can't do that.

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.

What exactly does the http-equiv value 'Content-Security-Policy' do?

I'm creating a mobile application using Apache Cordova/Adobe Phonegap, and this code snippet was automatically generated. It's giving me this error in the Console inside Google Chrome.
Refused to load the stylesheet
'https://fonts.googleapis.com/css?family=Open+Sans' because it
violates the following Content Security Policy directive: "style-src
'self' 'unsafe-inline'".
What exactly does this HTML meta element do?
<meta http-equiv="Content-Security-Policy" content="default-src * 'unsafe-inline'; style-src 'self' 'unsafe-inline'; media-src *" />
Short answer: If you want the https://fonts.googleapis.com/css?family=Open+Sans stylesheet to be loaded by browsers instead of blocked, then change the content value of the meta element so that it looks like this:
<meta http-equiv="Content-Security-Policy"
content="default-src * 'unsafe-inline';
style-src 'self' https://fonts.googleapis.com/ 'unsafe-inline'; media-src *" />
Longer explanation
That meta http-equiv="Content-Security-Policy" element provides a Content Security Policy that specifies some restrictions on what origin browsers can load the page assets from and what kinds of JavaScript and CSS content browsers will allow the page to specify inline.
As far as the specific part of those restrictions that’s relevant to the message you cite, it’s the restriction style-src 'self', which has the meaning “Only allow loading of external stylesheets from the same origin (same scheme+host+port) that the page is served from”.
So, because your page tries to load https://fonts.googleapis.com/css?family=Open+Sans—a stylesheet from a different origin than the page itself—and your meta http-equiv="Content-Security-Policy" includes a restriction that says “Don’t do that”, then browsers obey that restriction and refuse to load that stylesheet, and the message that you cite gets logged.
The <meta> tag provides Metadata (data about data) about the Web page. It's not displayed on the page, but it is parsed through by the browser.
Read more about the <meta> tag here.
Regarding the Meta tag in question, the Content-Security-Policy meta-tag allows you to reduce the risk of XSS attacks by allowing you to define where resources can be loaded from, preventing browsers from loading data from any other locations. This makes it harder for an attacker to inject malicious code to your site, as worded from this answer.