Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add_header X-Frame-Options SAMEORIGIN is added somewhere in NextCloud 13 #8207

Closed
p3x-robot opened this issue Feb 6, 2018 · 68 comments
Closed

Comments

@p3x-robot
Copy link

p3x-robot commented Feb 6, 2018

Steps to reproduce

In the whole /etc/nginx it is only just one place where is:

if ( $x_frame_options = "") {
        set $x_frame_options "SAMEORIGIN";
}
ssl on;
#gzip off;
#add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header Strict-Transport-Security "max-age=31536000; " always;
add_header X-Frame-Options $x_frame_options;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";

Expected behaviour

On my server it is right and every web sites, like this:
image

Actual behaviour

But in NextCloud 13 somewhere it adds in itself and because it adds 2 times for sure and is not NGINX or PHP, because I can show you many pictures, that is right:
image

Actually, I only use in /etc/nginx so it not anywhere, I look for, and I only there in NGINX:

root@server:/etc/nginx# find -type f | xargs egrep -i x-frame-options
./default-ssl-base.conf:add_header X-Frame-Options $x_frame_options;

So only once!

Server configuration

Operating system:
Linux server 4.12.0-2-amd64 #1 SMP Debian 4.12.13-1 (2017-09-19) x86_64 GNU/Linux

Web server:
nginx/1.13.8

Database:
mariadb Ver 15.1 Distrib 10.1.29-MariaDB, for debian-linux-gnu (x86_64) using readline 5.2

PHP version:
PHP 7.2.1-1 (cli) (built: Jan 5 2018 11:21:04) ( NTS )

Nextcloud version: (see Nextcloud admin page)
13

@p3x-robot
Copy link
Author

Actually I found this:
lib/private/legacy/response.php: header('X-Frame-Options: SAMEORIGIN'); // Disallow iFraming from other domains

@p3x-robot
Copy link
Author

If I remove this code, then my Nginx works, but it places dual headers and it senses that my config is wrong.

@p3x-robot
Copy link
Author

lib/private/legacy/response.php line 262. that is the bug

@p3x-robot
Copy link
Author

This is the actual bug (i commented and now all warning removed):
image

@p3x-robot
Copy link
Author

image

@MorrisJobke
Copy link
Member

This is the actual bug (i commented and now all warning removed):

We don't support that this is set by the web server. The Nginx should not add this header. Fro your point in the call route we are not able to detect if it will be added by the web server or not and thus we add it there because this then needs fewer tweaking of the webserver itself.

This is thus not a bug but an enhancement to also support web servers that somehow set it.

@MorrisJobke
Copy link
Member

See also #4605, #4863, #5246

@J0WI
Copy link
Contributor

J0WI commented Feb 7, 2018

Some headers are set in PHP, some are set in .htaccess/nginx. This inconsistency is really bad.

I found them on three different locations:

$policy = 'default-src \'self\'; '
. 'script-src \'self\' \'unsafe-eval\' \'nonce-'.\OC::$server->getContentSecurityPolicyNonceManager()->getNonce().'\'; '
. 'style-src \'self\' \'unsafe-inline\'; '
. 'frame-src *; '
. 'img-src * data: blob:; '
. 'font-src \'self\' data:; '
. 'media-src *; '
. 'connect-src *; '
. 'object-src \'none\'; '
. 'base-uri \'self\'; ';
header('Content-Security-Policy:' . $policy);
header('X-Frame-Options: SAMEORIGIN'); // Disallow iFraming from other domains
// Send fallback headers for installations that don't have the possibility to send
// custom headers on the webserver side
if(getenv('modHeadersAvailable') !== 'true') {
header('X-XSS-Protection: 1; mode=block'); // Enforce browser based XSS filters
header('X-Content-Type-Options: nosniff'); // Disable sniffing the content type for IE
header('X-Robots-Tag: none'); // https://developers.google.com/webmasters/control-crawl-index/docs/robots_meta_tag
header('X-Download-Options: noopen'); // https://msdn.microsoft.com/en-us/library/jj542450(v=vs.85).aspx
header('X-Permitted-Cross-Domain-Policies: none'); // https://www.adobe.com/devnet/adobe-media-server/articles/cross-domain-xml-for-streaming.html
}

https://github.com/nextcloud/documentation/blob/b7dec9a1cab21cf637914073b096eeda44608f1c/admin_manual/installation/nginx.rst#nextcloud-in-the-webroot-of-nginx
https://github.com/nextcloud/documentation/blob/b7dec9a1cab21cf637914073b096eeda44608f1c/admin_manual/configuration_server/harden_server.rst#serve-security-related-headers-by-the-web-server

Things are even worse if you run NextCloud behind a reverse proxy. The headers in the PHP file are not really customizable.
I would prefer setting them only in the server config and display a warning in the setup check.

@p3x-robot
Copy link
Author

p3x-robot commented Feb 7, 2018

@MorrisJobke Yeah, it says add it in NGINX, then you tell me to remove from NGINX. so which one we should use??? I think server settings is better, what do you think?

@p3x-robot
Copy link
Author

Right now it is chaos.

@p3x-robot
Copy link
Author

@J0WI yeah, exactly, what i mean, you cought it!

@J0WI
Copy link
Contributor

J0WI commented Feb 7, 2018

From a security perspective it also makes more scene to add security settings in the server config, which is harder to hijack in the case of a possible vulnerability in the PHP app.

Edit: And the webserver is also able to set the security headers if PHP is broken for whatever reason.

@p3x-robot
Copy link
Author

@J0WI Server is better, but if you want to use PHP, you should comment properly, i think, but of course, we cannot document, and code and fix and etc at once. So understand. I will remove the NGINX settings and I purely set it up for PHP, that's the best right? Like add modHeadersAvailable to the ENV. That's in done on PHP without NGINX or APACHE.

@J0WI
Copy link
Contributor

J0WI commented Feb 7, 2018

@p3x-robot you can also use proxy_hide_header or fastcgi_hide_header in your nginx config to hide the headers set by PHP:

proxy_hide_header X-Content-Type-Options;
fastcgi_hide_header X-XSS-Protection;

@p3x-robot
Copy link
Author

well, i just change my server, removed that and that's it. :) it works, awesome. THANKS!

@MorrisJobke
Copy link
Member

The biggest problem with that is that also there are users, that can't configure this in the webserver because they use a shared hoster. We try to make it as easy as possible for everybody :/ And sorry for the mess.

@MorrisJobke
Copy link
Member

Could you open a ticket (or even better a PR) in the documentation repo to give hints for this setting in the web server, @J0WI?

@p3x-robot
Copy link
Author

@MorrisJobke i just uncommeted that i hacked:
lib/private/legacy/response.php: header('X-Frame-Options: SAMEORIGIN'); // Disallow iFraming from other domains line 262 and i removed the X-Frame-Options from NGINX and then it works.
If now Nextcloud 13 works like this, of course we have ot upgrade and update our nginx server settings,
That's all, Now pass all checks...

@J0WI
Copy link
Contributor

J0WI commented Feb 7, 2018

The biggest problem with that is that also there are users, that can't configure this in the webserver because they use a shared hoster.

@MorrisJobke shared hoster tend to allow .htaccess (which is also shipped with NextCloud).
I can open a PR for the docs, but for me it's just a workaround. The issue is that headers are set by PHP (which is not really secure) and are not customizable.

@MorrisJobke MorrisJobke reopened this Feb 7, 2018
J0WI added a commit to J0WI/nextcloud-documentation that referenced this issue Feb 9, 2018
@tflidd
Copy link
Contributor

tflidd commented Feb 9, 2018

Is there a way for a php script to test if the headers are set by the webserver? So that php only adds them if they are not set via webserver. We could enable them by default and provide a configuration switch in case you can activate it on the webserver (the developers probably won't like to add another configuration option).

@MorrisJobke
Copy link
Member

Is there a way for a php script to test if the headers are set by the webserver? So that php only adds them if they are not set via webserver.

Not really, because the web server adds them after PHP send out the final response ... so it is more up to the web server to check if it is already set.

We could enable them by default and provide a configuration switch in case you can activate it on the webserver (the developers probably won't like to add another configuration option).

That would be the only option to handle this properly. We could even detect this in JS and give the admin that hint.

@J0WI
Copy link
Contributor

J0WI commented Feb 9, 2018

You could compare if the headers are only set on PHP reposes or also on static resources. But that's again just a hacky workaround.

@tflidd
Copy link
Contributor

tflidd commented Feb 10, 2018

So what's the plan here? A new config option for future versions (NC 14+)? How do we handle this in NC 13, remove the additional headers in the nginx-config from documentation?

@Harmageddon
Copy link

Not sure if this is related or an entire new issue:
I'm running NextCloud 16.0.4 on Apache/2.4.39, PHP 7.2 CGI. For me, the headers are sent twice - once from the .htaccess and once from here:

if(getenv('modHeadersAvailable') !== 'true') {
header('Referrer-Policy: no-referrer'); // https://www.w3.org/TR/referrer-policy/
header('X-Content-Type-Options: nosniff'); // Disable sniffing the content type for IE
header('X-Download-Options: noopen'); // https://msdn.microsoft.com/en-us/library/jj542450(v=vs.85).aspx

Normally, this line should avoid running into the case shown above:

SetEnv modHeadersAvailable true

But the environment variable can't be retrieved by getenv and is not shown in a phpinfo either. Apparently, in some environments, only environment variables starting with HTTP_ can be set in the .htaccess. I tried it and if I change the variable to e.g. HTTP_MOD_HEADERS_AVAILABLE, it works in phpinfo as well as in the response.php.

Maybe someone who has more experience with Apache / PHP-CGI can tell whether this might be a solution for at least some of the issues discussed here?

@kesselb
Copy link
Contributor

kesselb commented Aug 27, 2019

But the environment variable can't be retrieved by getenv and is not shown in a phpinfo either. Apparently, in some environments, only environment variables starting with HTTP_ can be set in the .htaccess.

I don't see this with Apache/2.4.25 and PHP-FPM 7.2.21. Are you using mod_cgi? You are aware that this is super slow.

@Harmageddon
Copy link

@kesselb phpinfo says "CGI/FastCGI".

If I change it to FPM, neither modHeadersAvailable nor HTTP_MOD_HEADERS_AVAILABLE can be accessed by PHP - they seem to be prefixed with REDIRECT_. But FPM somehow seems to avoid sending the same headers twice, so the issue doesn't visibly appear there.

@kesselb
Copy link
Contributor

kesselb commented Aug 28, 2019

@Harmageddon mind to create a new issue? It seems to be a bit off topic.

@pgnd
Copy link

pgnd commented Dec 18, 2019

Ok, so I've re-read this a bunch o' times, and STILL have no clue how to fix this ...

atm, with NC18b (18.0.0.4), I'm getting reports of

The "X-Content-Type-Options" HTTP header is not set to "nosniff". This is a potential security or privacy risk, as it is recommended to adjust this setting accordingly.
The "X-Frame-Options" HTTP header is not set to "SAMEORIGIN". This is a potential security or privacy risk, as it is recommended to adjust this setting accordingly.
The "X-XSS-Protection" HTTP header doesn't contain "1; mode=block". This is a potential security or privacy risk, as it is recommended to adjust this setting accordingly.

Adding

more_clear_input_headers "X-Content-Type-Options" "X-Frame-Options" "X-XSS-Protection";

to my nginx config appears to have NO effect.

IIUC, there's a fix somewhere up there ^?

I prefer to keep headers in my webserver config -- particularly since it's a proxy in front of a number of various services, including NC.

What exactly is required to make these errors go away?

EDIT:
I've tested here with all variants,

fastcgi_hide_header X-Frame-Options;
fastcgi_hide_header X-XSS-Protection;
fastcgi_hide_header X-Content-Type-Options;
proxy_hide_header X-Frame-Options;
proxy_hide_header X-XSS-Protection;
proxy_hide_header X-Content-Type-Options;
more_clear_input_headers "X-Content-Type-Options";
more_clear_input_headers "X-Frame-Options";
more_clear_input_headers "X-XSS-Protection";

None have any effect -- EXCEPT

proxy_hide_header X-Content-Type-Options;

DOES remove its respective error ...

@J0WI
Copy link
Contributor

J0WI commented Dec 18, 2019

@pgnd
Copy link

pgnd commented Dec 18, 2019

@J0WI yep, long ago

@juliusknorr
Copy link
Member

I also cannot reproduce this on my phpfpm setup although I have seen this in the past as well. Could anyone of you share the output of a info.php file with the following content that is added to your webroot and opened in the browser:

<?php
phpinfo();

It should show the env variable similar to that:
image

@juliusknorr
Copy link
Member

There also seems to be a clear_env configuration flag for phpfpm, could you also check the value of that? https://www.php.net/manual/en/install.fpm.configuration.php

@pgnd
Copy link

pgnd commented Dec 18, 2019

@juliushaertl

for phpinfo(), here,

...
$_SERVER['modHeadersAvailable']	true
...

and,

grep clear  php-fpm.conf
  clear_env = no

@pgnd
Copy link

pgnd commented Dec 23, 2019

@juliushaertl did you need add'l/other info?

@kesselb
Copy link
Contributor

kesselb commented Dec 23, 2019

Is this issue still relevant? The code in question #8207 (comment) has been changed with Nextcloud 17.

To any response (from nextcloud) the Content-Security-Policy is added. The fallback code to add Referrer-Policy, X-Content-Type-Options, X-Download-Options, X-Frame-Options, X-Permitted-Cross-Domain-Policies, X-Robots-Tag and X-XSS-Protection only runs if modHeadersAvailable is not present (or has a value <> true).

So if anyone asks "how can I disable the security headers set by nextcloud" the answer is: SetEnv modHeadersAvailable true for apache2 or fastcgi_param modHeadersAvailable true; for nginx. I've just tested both ways and they work for me.

Any objections?

@pgnd
Copy link

pgnd commented Dec 23, 2019

@kesselb

here, with clean install of NC tag

	v18.0.0beta3

checking

	sudo -u wwwrun php occ status
		- installed: true
		- version: 18.0.0.5
		- versionstring: 18.0.0 Beta3
		- edition:

in Nginx config

	grep modHeadersAvailable fastcgi_params
		fastcgi_param modHeadersAvailable true;

after login, nav to

	.../cloud/settings/admin/overview

still reports

    The "X-Content-Type-Options" HTTP header is not set to "nosniff". This is a potential security or privacy risk, as it is recommended to adjust this setting accordingly.
    The "X-Frame-Options" HTTP header is not set to "SAMEORIGIN". This is a potential security or privacy risk, as it is recommended to adjust this setting accordingly.
    The "X-XSS-Protection" HTTP header doesn't contain "1; mode=block". This is a potential security or privacy risk, as it is recommended to adjust this setting accordingly.

So, clearly, still getting these ^^

Have I missed something in my config?

@kesselb
Copy link
Contributor

kesselb commented Dec 23, 2019

Have I missed something in my config?

How should I know? ;) Feel free to visit help.nextcloud.com and share your configuration. Also make sure that the headers are not sent twice like the other report.

With nextcloud 17 the X-Frame-Options are sent conditionally like the other headers too. There is a way to disabled this that works for most people. Is anyone able to provide a docker-compose.yml (or a description how to configure nginx and php-fpm) to reproduce this issue?

What do you think @juliushaertl @J0WI?

@MichaIng
Copy link
Member

MichaIng commented Mar 5, 2020

@pgnd
Just to clean it up:

Also did you check which headers actually arrive at the client (and how often)? curl -IL your.domain.name

@youradds
Copy link

@MichaIng this is still not correct. I have added the headers as per https://docs.nextcloud.com/server/latest/admin_manual/installation/nginx.html , and also set:

fastcgi_param modHeadersAvailable true; #Avoid sending the security headers twice

Yet I still get double headers!

curl -I https://drive.foo.com/
HTTP/2 302
server: nginx
date: Thu, 11 Jun 2020 07:29:57 GMT
content-type: text/html; charset=UTF-8
location: https://drive.foo.com/index.php/login
set-cookie: ockk0f3puuto=fqsng8tvcii0j1o0mo0pqmme99; path=/; secure; HttpOnly
expires: Thu, 19 Nov 1981 08:52:00 GMT
cache-control: no-store, no-cache, must-revalidate
pragma: no-cache
set-cookie: oc_sessionPassphrase=HriJPt%2Bh6SV0OUxIXTQXfVS1hMPH2129Sk2ftLPraKPDSEeRrVSeSVhxSV6kjpOITG6RGQMZMvlYQalHQrB5BVr7gbCEuWP0x2VAfW7I4iCN3Ue2PhXqWF9sa9Y8tFli; path=/; secure; HttpOnly
content-security-policy: default-src 'self'; script-src 'self' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; frame-src *; img-src * data: blob:; font-src 'self' data:; media-src *; connect-src *
x-xss-protection: 1; mode=block
x-content-type-options: nosniff
x-frame-options: SAMEORIGIN
x-robots-tag: none
x-download-options: noopen
x-permitted-cross-domain-policies: none
referrer-policy: no-referrer
x-content-type-options: nosniff
x-download-options: noopen
x-frame-options: SAMEORIGIN
x-permitted-cross-domain-policies: none
x-robots-tag: none
x-xss-protection: 1; mode=block

Is there a setting we can call that will stop the PHP script from sending its own headers? Cos if I comment out ALL the add_header parts from my nginx config, it works fine! (which means ownCloud itself is adding them!)

@MichaIng
Copy link
Member

Here the headers are set:

if (getenv('modHeadersAvailable') !== 'true') {
header('Referrer-Policy: no-referrer'); // https://www.w3.org/TR/referrer-policy/
header('X-Content-Type-Options: nosniff'); // Disable sniffing the content type for IE
header('X-Download-Options: noopen'); // https://msdn.microsoft.com/en-us/library/jj542450(v=vs.85).aspx
header('X-Frame-Options: SAMEORIGIN'); // Disallow iFraming from other domains
header('X-Permitted-Cross-Domain-Policies: none'); // https://www.adobe.com/devnet/adobe-media-server/articles/cross-domain-xml-for-streaming.html
header('X-Robots-Tag: none'); // https://developers.google.com/webmasters/control-crawl-index/docs/robots_meta_tag
header('X-XSS-Protection: 1; mode=block'); // Enforce browser based XSS filters
}

Clearly only if modHeadersAvailable is no true and I just verified it's working as expected. Please assure the location where you added modHeadersAvailable, inside the .php files location directive in front of fastcgi_pass.

@youradds
Copy link

@MichaIng Thanks for the reply . It looks like it needed adding into the /etc/nginx/fastcgi_params file, rather than inside the server {} bit. Done, and those messages have gone away :)

@MichaIng
Copy link
Member

MichaIng commented Jun 11, 2020

Ah yes that is an alternative, although it is loaded likely by other web applications as well, which do not require it. The community Nginx config contains:

include fastcgi_params;

which loads this file. If you add fastcgi_param modHeadersAvailable true; right below this, it will work as well for Nextcloud only. However it doesn't matter much since it does not break anything else 😉.

@G2G2G2G

This comment has been minimized.

@MichaIng

This comment has been minimized.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests