I'm trying to use Content-Security-Policy (CSP) headers for a site that has social media buttons (youtube, twitter, facebook). However these widgets run scripts on a poorly specified list of 3rd party sites. The social media sites don't specify all the sites their scripts will access and so you need to run your page and one-by-one look and see the domains that were blocked, then add them to the CSP header.
This seems very fragile. If the social media sites change their scripts and add new domains, the page will break because the browser will block access to the new domain.
CSP is very effective in stopping XSS, but it seems social media sites do not provide buttons / widgets designed to work with it. At a minimum, they should require only ONE domain and should specific what that domain is.
I end up with a CSP header like:
Content-Security-Policy: default-src 'self' https://www.google.com http://csi.gstatic.com http://www.google-analytics.com https://apis.google.com https://accounts.google.com https://platform.twitter.com https://www.youtube. com http://platform.twitter.com; img-src 'self' data: https://www.google.com http://www.google-analytics.com http://ssl.gstatic.com https://ssl.gstatic.com data:; style-src 'self' https://fonts.googleapis.com 'unsafe-inline'; font-src 'self' https://fonts.gstatic.com data:
Is there a better way to do this?
Related
I want to integrate the Google Adwords conversion script to my web app, therefore I have to extend my CSP rule to allow this one.
I face problem allowing https://www.google.xx/ads/ into script-src policy because it looks like, depending of the region, that the domain gonna change.
For example, if I access the page in Switzerland, the allowed script should be https://www.google.ch/ads/ but if I access it in Romania, the allowed script should be https://www.google.ro/ads/ etc.
How could I allow all domains in my policy without having to list all countries and regions of the world?
Thx in advance for the help
P.S.: Console stacktrace
Refused to load the script 'https://www.google.ro/ads/user-lists/8...
P.P.S: I tried to whitelist it using nonce but it looks like that the following script can't be whitelisted like this
<script nonce="random-base64">
window.dataLayer = window.dataLayer || [];
var gtag = function gtag(){ // <---- There, CSP problem
dataLayer.push(arguments);
};
gtag('js', new Date());
gtag('config', 'SOMETHING');
</script>
P.P.P.S.: Same problem with img-src btw. Google Adwords CSP (content security policy) img-src
How could I allow all domains in my policy without having to list all countries and regions of the world?
You don't. There's no TLD-level whitelist; and for good reason. You can't possibly guarantee that a different TLD with the same main domain is the same entity, so a wildcard would make no sense.
With Google Adsense as well I've had this issue, and basically your only options are an excessive whitelist (manually listing every possible domain and hoping they don't add new ones), an even more excessive global whitelist (this is extremely not recommended), or just listing the most common countries of origin and accepting that some geolocales will be excluded.
The third option is generally the best, I use adsense not adwords, but most of my traffic comes from the US and I'm willing to lose ad impressions from a few specific countries with low hit counts to keep from maintaining an absurd list.
The only real solution here can come from Google: they have to stop serving resources from different TLDs (this is, IMO, a terrible practice in all cases since HREF LANG tags are a thing anyway). Kind of surprised Google is even still doing it in 2018 with CSP being a moderately big deal but here we are.
As for img-src just use https: IMO. It's okay to over-eagerly load images if you're dealing with an unpredictable third party domain set. CSP is meant to block dangerous content. img-src is a pretty low risk factor and would pretty much have to be mixed with a second exploit to cause real harm.
I'm forcing https to access my website, but some of the contents must be loaded over http (for example video contents can not be over https), but the browsers block the request because of mixed-contents policy.
After hours of searching I found that I can use Content-Security-Policy but I have no idea how to allow mixed contents with it.
<meta http-equiv="Content-Security-Policy" content="????">
You can't.
CSP is there to restrict content on your website, not to loosen browser restrictions.
Secure https sites given users certain guarantees and it's not really fair to then allow http content to be loaded over it (hence the mixed content warnings) and really not fair if you could hide these warnings without your users consent.
You can use CSP for a couple of things to aid a migration to https, for example:
You can use it to automatically upgrade http request to https (though browser support isn't universal). This helps in case you missed changing a http link to https equivalent. However this assumes the resource can be loaded over https and sounds like you cannot load them over https so that's not an option.
You can also use CSP to help you identify any http resources on you site you missed by reporting back a message to a service you can monitor to say a http resource was attempted to be loaded. This allows you identify and fix the http links to https so you don't have to depend on above automatic upgrade.
But neither is what you are really looking for.
You shouldn't... but you CAN, the feature is demonstrated here an HTTP PNG image converted on-the-fly to HTTPS.
<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">
There's also a new permissions API, described here, that allows a Web server to check the user's permissions for features like geolocation, push, notification and Web MIDI.
When google javascript client library is used in chrome extension, 'unsafe-eval' permission is required when response type is id_token. Is there any way to avoid this?
last time I checked the JSAPI client library wasn't supported in Chrome Extensions. Even if it is, I would strongly suggest you avoid using it.
It's easier and safer to use the built-in chrome.identity API to handle the oauth and then roll your own Google API calls.
Using eval() function in a Chrome Extension requires 'unsafe-eval' permission to be declared in the manifest.json, regardless the presence of the Goole Javascript Client Library inside that extension.
Evaluated JavaScript. The policy against eval() and its relatives like setTimeout(String), setInterval(String), and new Function(String)
can be relaxed by adding 'unsafe-eval' to your policy:
"content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'"
However, we strongly recommend against doing this. These functions are
notorious XSS attack vectors.
See the official Google Documentation for more information about
Content Security Policy.
So http://cdnjs.com/ and some of my peers are recommending that we use // in front of the resource. What is this term or technology called? As I understand the purpose is so that http or https is preserved. However when I want to google say yepnope's compatibility with it, what do I call it?
It's a "relative URL" — in this case, a URL with no protocol part (and so it uses the protocol from its parent document), just like /foo.html is a relative URL with no protocol or servername parts (and so uses the protocol and server of its parent document).
The purpose of protocol-relative URLs is that they are portable between http and https documents (and a teensy bit shorter). So if you have:
<link rel="stylesheet" href="//cdnjs.cloudflare.com/etc.css">
...on the page http://example.com, the URL expands to
http://cdnjs.cloudflare.com/etc.css
...but if it's on the page https://example.com, it expands to
https://cdnjs.cloudflare.com/etc.css
...and you don't get the "mixed secure and insecure content" warning from the browser.
One slight downside is if you're doing some quick-and-dirty local testing using files you've opened directly from the file system, their protocol is file:, and so the URL ends up being
file://cdnjs.cloudflare.com/etc.css
...which probably doesn't refer to a valid resource on your computer (and leads to questions on SO).
More on my blog: Skipping the protocol
I recently ran across a website that had some interesting styling on a select element. I went to investigate and found this (names changed to protect the innocent):
<script type="text/javascript" src="//www.domain.tld/file.js"></script>
It works despite HTTP: being omitted. What is the purpose of leaving off the protocol?
It will use the protocol you're already using. Useful for sites with both https and http versions.
So if you're on https://www.domain.tld/file.js the script will be https://www.domain.tld/file.js.
If you're on http://www.domain.tld/ the script will be http://www.domain.tld/file.js.
i believe this is short hand for a relative path to the protocol. So it should use the same protocol as is being used for that session. e.g if you grabbed that page with http, then this url is relative to http protocol
The purpose is that the scheme (ie. http or https) can be determined relative to the containing page. This is useful if you have a common piece of code included in multiple pages that can be served via http or https.
The purpose is to "use the same protocol as in the current URL" -- presumably (?) useful if the page can be reached both as http: and https: (I have a hard time thinking of other protocols yet that it might be useful for, and even this one is not a clear-cut use case).