Content security policy - different behaviour windows vs linux - apache

I have a wordpress website that runs on a LAMP system.
I tried to improve security (I'm far from being an expert!) and added a CSP header.
Header set Content-Security-Policy "default-src 'self'; font-src 'self' data: https://fonts.gstatic.com; frame-src https://www.google.com https://www.youtube.com; img-src 'self' https://secure.gravatar.com; script-src 'self' 'unsafe-inline' ; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; object-src 'none'"
What I don't understand: If I remove the unsafe-inline from the script-src my calendar widget does not load anymore on a windows browser (tested both firefox and chrome). But it works on a Linux browser (Firefox).
Is this a bug in apache2, in the windows browsers or in the calender wp plugin?
I'm confused. :-)

It doesn't look like an Apache bug, it just sends the CSP as a string without even understanding what's in it.
Of course you can use some User Agent conditions in the httpd.conf like:
SetEnvIfNoCase User-Agent "Linux x86_64" noCSP=1
and to publish CSP relying on noCSP flag to exclude CSP header for some kinds od user agents.
But you can easily clarify that and ensure you have the same CSP header for the Windows/Linux browsers.
I think a WP calendar plugin uses some inline scripts which are blocked in absence of 'unsafe-inline'. You can check accourding CSP errors in the browser console of windows browser.
Maybe you disabled CSP in your Linux Firefox browser (about:config page -> security.csp.enable -> false) or have some extensions which disable CSP.

So the different Windows/Linux behaviour comes from the Laboratory plugin that was running in my Linux Firefox.
I have to check with the plugin author why unsafe-inline is required.

Related

Safari Gives Error "Refused to connect to _____ because it does not appear in the connect-src directive of the Content Security Policy."

I have a online whiteboard that Safari users cannot connect to. They get the following from the console.
Refused to connect to wss://whiteboard.[MYDOMAIN].com/[MOREPATHSTUFF] because it does not appear in the connect-src directive of the Content Security Policy.
Only Safari does this. Chrome, FF, Edge, etc. work fine. I've looked over other SO related posts and it seems that Safari requires something like...
<meta http-equiv="Content-Security-Policy" content="
default-src * data: blob: ws: wss: gap://ready file://*;
style-src * 'unsafe-inline';
script-src * 'unsafe-inline' 'unsafe-eval';
connect-src * ws: wss:;">
I have no idea what all of this means though. All I want is for Safari to allow the connection and all should be well. Thanks for the consideration on how to make that happen.
I've looked over other SO related posts and it seems that Safari requires something like...
You already have a Content Security Policy (CSP) been published via an HTTP header or meta tag (how to check it), because a violation message appears in the browser console.
Publishing the second CSP cannot relax the resulting policy, since the first CSP will still perform a blocking.
That's why you couldn't fix the problem by adding a meta tag or HTTP header.
You have to figure out where the first CSP is published and to make changes to it.
Only Safari does this. Chrome, FF, Edge, etc. work fine.
Safari supports the connect-src directive, so its behaviour should not differ from Chrome/Firefox/Edge except one thing: Safari does not support upgrade ws: to wss:.
In case of connect-src ws:, the Chrome/Firefox/Edge will apply connect-src ws: wss: policy, but Safari does not.
I bet you have connect-src ws: in the CSP, therefore all connection to wss: are blocked.
When you find where your CSS is published, just add wss://whiteboard.[MYDOMAIN].com to connect-src directive.
Note: if you are using the default-src directive instead of connect-src - then you need to add wss://whiteboard.[MYDOMAIN].com into it.
Update:
How CSP header can be issued
A). A CSP header can be published in your web app itself (Helmet middleware, specific packages for managing HTTP headers, direct issue an HTTP header via res.setHeader() and so on).
B). CSP header can be published by server. For Nginx it should be add_header Content-Security-Policy "default-src ... "; in the server config. Several folders can be used for that but etc/nginx/conf.d is preferred, others are deprecated.
What if I publishes CSP header in both ways A) and B) at the same time?
Server works after your web app software did all job, therefore web-server (or proxy-server) should override an HTTP header with the same name. So server can override any HTTP header published by web app.
In some cases it's not work and you can see that 2 CSP headers been published. Even in this case you can make a trick:
proxy_hide_header Content-Security-Policy;
and then immediately under that, add header how fo you need it:
add_header Content-Security-Policy "default-src 'self';";
This can be used as a temporary solution until you figure out where the header is really published.
CSP has some unintuitive traits. One is:
Websockets like wss://example.com are not captured by wildcards such as *.example.com or even *
In order to allow the websockets - you need to explicitly add them with wss://example.com or even ws: wss:
If you only want to allow anything on the connect-src, then adding
connect-src * ws: wss:; to your policy should work (as you mentioned).

MS Edge (Chromium) do not display PDF documents with Content Security Policy set (ERR_BLOCKED_BY_CLIENT)

I have a web application that provides links to display PDFs.
The Content-Security-Policy is set in the apache configuration (httpd.conf)
My problem is now that in MS Edge (chromium based) is not opening/displaying the PDFs.
In Firefox on clicking the Link the new Tab is opened and the PDF gets loaded and displayed.
In MS Edge on clicking the Link the new Tab is opened but it is displaying an error:
example.domain.org is blocked
Requests to the server have been blocked by an extension.
Try disabling your extensions.
ERR_BLOCKED_BY_CLIENT
There is no extension installed, it is the same for incognito mode.
After testing the Content-Security-Policy it seems that the chromium based browsers do handle the CSP "sandbox" very different to FireFox. Without the "sandbox" policy it is working like in firefox.
Header set Content-Security-Policy "base-uri 'self' example.domain.org.com; default-src 'self' example.domain.org.com; form-action 'self' example.domain.org.com; frame-src http://example.domain.org.com; font-src 'self' https://fonts.googleapis.com/ https://fonts.gstatic.com/ https://fonts.googleapis.com/css data:; img-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' https://fonts.googleapis.com 'unsafe-inline'; sandbox allow-forms allow-scripts allow-same-origin allow-popups;"
Is there a way to add the basic CSP sandbox (with specifiers like allow-forms allow-scripts allow-same-origin allow-popups) but still allow opening PDFs within the chromium based browsers?
Or to remove the CSP sandbox only for PDFs trough some config in httpd.conf?

Safari 11 gets SecurityError (DOM exception 18) when accessing localStorage

I just upgraded to Safari 11. I've been debugging my WebApp by opening the html file directly with Safari. After the upgrade it gets "SecurityError (DOM Exception 18) The operation is insecure when the app accesses localStorage.
Here's my security policy tag;
<meta http-equiv="Content-Security-Policy"
content="default-src 'self' file:// *;
style-src * 'self' 'unsafe-inline' 'unsafe-eval';
script-src * 'self' 'unsafe-inline' 'unsafe-eval';"
>
This worked fine on previous versions of Safari and on Chrome, FIreFox etc.
Any thoughts?
I found the answer! Set "Disable local file restrictions" in the Develop menu.

Content Security Policy style-src refuses to load in Safari

Using Safari 11.0 I am receiving an error trying to load a CSS resource on a website I maintain. The page loads fine in Chrome and Firefox, and used to load fine in Safari, so I'm not sure how to resolve it. I'm guessing I need to modify the Content-Security-Policy header.
The specific error from the Safari console is Refused to load https://****.com/css/styles.css because it does not appear in the style-src directive of the Content Security Policy. As a result of this, the styles.css file isn't loading and the website is rendered incorrectly.
The security headers for the website (set via caddy) are:
Content-Security-Policy default-src 'self' https:; script-src 'self'; style-src 'self'; object-src 'none'
Content-Type text/html; charset=utf-8
Referrer-Policy strict-origin
Server Caddy
Strict-Transport-Security max-age=31536000; includeSubDomains; preload
Change the style-src part of the Content-Security-Policy header value so that it’s instead style-src 'self' https://****.com. That is, replace the ****.com in https://****.com with whatever the actual hostname is.

Content Security Policy not working with SHA256

I'm creating a Content Security Policy on RedHat 6 Apache 2.2 for some html files with JavaScript links to Google. I have added the following code the virtualhost of the site in httpd.conf file.
Header always set Content-Security-Policy-Report-Only: "default-src 'self' https:; script-src 'self' https: https://www.google-analytics.com https://ajax.googleapis.com; style-src inline: 'self' https: 'sha256-j0bVhc2Wj58RJgvcJPevapx5zlVLw6ns6eYzK/hcA04=' https://www.google-analytics.com https://ajax.googleapis.com; font-src 'self'; img-src 'self' https: data: https://www.google-analytics.com; form-action 'self'; frame-ancestors 'none'; connect-src 'self' https: https://www.google-analytics.com; child-src 'self'"
Cannot get the policy to work unless I use 'unsafe-inline' which I would prefer not to. Latest Chrome browser in developer mode says to add SHA256 hash which I did (see below). Even though I added the recommended SHA256 hash Chrome still asks me to add it????
Am I not handling SHA256 hash correctly? Any help will be appreciated.
From Chrome developers console.
Refused to apply inline style because it violates the following
Content Security Policy directive: "style-src inline: 'self' https:
'sha256-j0bVhc2Wj58RJgvcJPevapx5zlVLw6ns6eYzK/hcA04='
https://www.google-analytics.com https://ajax.googleapis.com". Either
the 'unsafe-inline' keyword, a hash
('sha256-j0bVhc2Wj58RJgvcJPevapx5zlVLw6ns6eYzK/hcA04='), or a nonce
('nonce-...') is required to enable inline execution.
EDIT: This is discussed in this bug:
https://bugs.chromium.org/p/chromium/issues/detail?id=546106
Not totally following what the bug says but it seems the spec only allows sha256 hashes for script and style tags and not for inline scripts and styles. It appears you are going to have to add a 'unsafe-hashed-attributes' attribute to your policy to make it work.
However not totally clear if that is just to fix the script part or also styles, nor if it has been released. It definitely won't have made it to iOS devices that also use WebKit so, for now, I would just allow unsafe-inline for styles.
ORIGINAL ANSWER (before above answer was added but leaving to avoid confusion as comments added below).
I see a few problem:
The error mention the Content Security Policy but your example config is the Report Only header. I've seen issues when using both Content-Security-Policy and Content-Security-Policy-Report-Only. They should be independent but are not. Might be worth trying without one to see if that's the problem.
Your style source includes inline: which is not valid syntax AFAIK
You include the general https: directive and then also specific https sites (https://www.google-analytics.com https://ajax.googleapis.com)