I’m hosting my own Nextcloud 11.0.3 on my Raspbian Jessie with Nginx 1.6.2 from the repo. It’s being hosted as a subdir of nginx and I’ve set my own CSP header. However, I want to make use of the nonce security which the latest draft specification of CSP 3.0 supports, but I could not find this anywhere in the Nextcloud 11 Server Administration Manual. How can I make use of the nonces in CSP with my setup?
CSP 3.0 was introduced in NC 12: https://nextcloud.com/blog/welcome-to-nextcloud-12/
Such new features are not backported to older versions, you could try to fiddle it in yourself but only if you have very good reasons not to use NC 12 yet.
Thanks for your reply, but that’s not true. Your link clearly states: “Nextcloud 11 introduced better password handling, CSP 3.0 and Same-site Cookies support improvements and expanded brute force protection.” If you follow that link it confirms Nextcloud 11 supports CSP 3.0 with cryptographic nonces: https://nextcloud.com/blog/nextcloud-11-delivers-verified-security-improvements/
“Content Security Policy v3.0 Support with nonce instead of “self” for script-src”
I can even see the nonces being part of the generated HTML pages of my Nextcloud 11.0.3:
So, how can I use them to my advantage in my CSP header?
After some troubleshooting I noticed that my web server sends two CSP headers:
- The static Nginx CSP header (my own);
- The dynamic Nextcloud CSP header (with a matching nonce every request).
This causes the client to receive duplicate CSP headers, and apparently the Nginx header takes precedence. Since I run more services than Nextcloud on my web server, removing the CSP header in Nginx is not an option. Is there a best practice to fix this issue when dealing with multiple CSP headers for multiple services? Is there, for example, a way for the Nextcloud header to take precedence when explicitly connecting to my Nextcloud URL?
This I believe might be down to @LukasReschke to answer, but in the meantime since this isn’t unique to Nextcloud a quick Google or two may give you the answer you need.
You could try the following:
Since you are running nextcloud in a subdir you could remove the nginx-headers for requests within that subdir. If a new add_header directive in a subcontext is declared, nginx removes for that subcontext all add_header directives declared on a higher level. From nginx-docu (http://nginx.org/en/docs/http/ngx_http_headers_module.html#add_header):
There could be several add_header directives. These directives are inherited from the previous level if and only if there are no add_header directives defined on the current level.
So if you add a header on subdir level like
add_header dummy "dummy";
(which doesn’t exist and will be ignored by browsers), headers declared on a higher level will not be sent.
But then you also need to make sure that those lines are not present in the subdirectory configuration - otherwise the headers created by nextcloud won’t be sent:
#Avoid sending the security headers twice
fastcgi_param modHeadersAvailable true;
This is indeed true from what I have read and can confirm when creating subdirs myself. Whenever I set a new header in a subdir, all headers I set at the parent are no longer inherited. However, this doesn’t seem to be the case for my Nextcloud subdir, which also sets a few security headers (like HSTS), yet still inherits the HPKP, Referrer-Policy and Expect-CT headers I have up top. I’m using this Nginx subdir configuration: https://docs.nextcloud.com/server/11/admin_manual/installation/nginx_nextcloud_9x.html
Can this behaviour be explained? I kinda wish to do the same for other services by simply setting the CSP header in a subdir while it still inherits the other security headers from its parent. Otherwise I guess I’m stuck copy-pasting all my security headers to every subdir I have. This feels overly redundant and it’s tedious to update every HPKP header every time I renew my Let’s Encrypt signed certificate. What do you guys do in these cases?
You could put the headers which are always needed in a separate file and include them at the different locations to your configuration. So you only have to change that single file, if anything has to be changed.