HTTP header security options

I use Nextcloud with Apache 2.4.27. According to the “Security & setup warnings” in the admin panel, I set the following options in my Apache’s httpd.conf:

Header set X-XSS-Protection "1; mode=block"
Header set X-Content-Type-Options nosniff
Header set X-Robots-Tag none
Header set X-Frame-Options SAMEORIGIN

With these additional settings, the security & setup warnings disappear. However, when I test my web server’s security, using the security test at https://www.htbridge.com/websec/, it tells me that I should use the following settings

Header always set X-XSS-Protection "1; mode=block"
Header always set X-Content-Type-Options nosniff
Header always set X-Robots-Tag none
Header always set X-Frame-Options SAMEORIGIN

and if I do that, I get a good security grade (B). However, with those settings, Nextcloud claims the following:

The “X-XSS-Protection” HTTP header is not configured to equal to “1; mode=block”. This is a potential security or privacy risk and we recommend adjusting this setting.
The “X-Content-Type-Options” HTTP header is not configured to equal to “nosniff”. This is a potential security or privacy risk and we recommend adjusting this setting.
The “X-Robots-Tag” HTTP header is not configured to equal to “none”. This is a potential security or privacy risk and we recommend adjusting this setting.
The “X-Frame-Options” HTTP header is not configured to equal to “SAMEORIGIN”. This is a potential security or privacy risk and we recommend adjusting this setting.

Why do I see these warnings? I would expect that the options are always set if I use the keyword ‘always’ in my apache config. If I remove it, warnings disappear in the admin panel, but I get an F grade for my web server’s security.

I am a bit confused now :-/

Not sure, external test are better in general. You can test yourself with curl -vvvv https://yourhost.com/nextcloud

What I could imagine is that apache always adds the header (for https://yourhost.com/nextcloud also for https://yourhost.com/nextcloud/index.php) and via Nextcloud only when you run through the script (so only with https://yourhost.com/nextcloud/index.php).

Shouldn’t these headers be hardcoded served by nextcloud? Hardening and Security Guidance — Nextcloud 12 Server Administration Manual 12 documentation

But as also written there:

For optimal security, administrators are encouraged to serve these basic HTTP headers by the Web server to enforce them on response.

In the default .htaccess there are indeed set without “always”:

  <IfModule mod_env.c>
    # Add security and privacy related headers
    Header set X-Content-Type-Options "nosniff"
    Header set X-XSS-Protection "1; mode=block"
    Header set X-Robots-Tag "none"
    Header set X-Download-Options "noopen"
    Header set X-Permitted-Cross-Domain-Policies "none"
    SetEnv modHeadersAvailable true
  </IfModule>

But as far as I understand I would agree that “always” should be also accepted by nextcloud.

Testing my server with https://www.htbridge.com/websec/ and giving explicitly the nextcloud subfolder (with .htaccess) there, I get A+ grade with all headers “properly set” without complaining the missing “always” :thinking: .

Try this tool:
https://tools.keycdn.com/curl

For just https://mydomain.com/nextcloud, I only get a permanent redirect to the index.php and only in the index.php, Nextcloud actually adds the header.

If you want to proof that the header is not set correctly or not analyzed, you need to show us how in both cases your header looks like. We then can perhaps push this to github in case the header-detection fails somehow.

1 Like

Hi,
thanks for your replies. I have tested my server with the https://tools.keycdn.com/curl. This is the result:

HTTP/2 301
date: Thu, 31 Aug 2017 13:52:38 GMT
server: Apache
strict-transport-security: max-age=15768000; includeSubDomains; preload
x-xss-protection: 1; mode=block
x-content-type-options: nosniff
x-robots-tag: none
x-frame-options: SAMEORIGIN
location: https://hb9fsx.ch/nextcloud/
content-length: 236
content-type: text/html; charset=iso-8859-1

HTTP/2 302
date: Thu, 31 Aug 2017 13:52:39 GMT
server: Apache
strict-transport-security: max-age=15768000; includeSubDomains; preload
x-xss-protection: 1; mode=block
x-content-type-options: nosniff
x-robots-tag: none
x-frame-options: SAMEORIGIN
x-powered-by: PHP/7.1.8
set-cookie: ocawkdp98rhh=56g2abc16jh9v0rh9rgh6setvq; path=/nextcloud; 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=Q1tu9zsbMJ3s5gnN55FngrgmmawBDDe3hGLN3ezvu0G5TbtS16Yf41Q0AjqGwU6nc0ZnHEVJMjDzUb3QD301bKSJksXbkf2D7wjZXUXlsdvlqpZYu8o5FGyZbWxvbQlX; path=/nextcloud; secure; HttpOnly
content-security-policy: default-src 'self'; script-src 'self' 'unsafe-eval' 'nonce-c2FnOGV0bmxCVnQ5dTZjSzY1b203VjNuMHozaUZkelVnWnR1c0lFQTh0dz06L1lkVElQYXhZaUVTODVWRGhhcDJqaDZmbW0zYVJ1cWN4czBtZy9CVWtlVT0='; 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';
x-frame-options: SAMEORIGIN
set-cookie: nc_sameSiteCookielax=true; path=/nextcloud; httponly;secure; expires=Fri, 31-Dec-2100 23:59:59 GMT; SameSite=lax
set-cookie: nc_sameSiteCookiestrict=true; path=/nextcloud; httponly;secure; expires=Fri, 31-Dec-2100 23:59:59 GMT; SameSite=strict
location: https://hb9fsx.ch/nextcloud/index.php/login
x-content-type-options: nosniff
x-xss-protection: 1; mode=block
x-robots-tag: none
x-download-options: noopen
x-permitted-cross-domain-policies: none
content-length: 0
content-type: text/html; charset=UTF-8

HTTP/2 200
date: Thu, 31 Aug 2017 13:52:39 GMT
server: Apache
strict-transport-security: max-age=15768000; includeSubDomains; preload
x-xss-protection: 1; mode=block
x-content-type-options: nosniff
x-robots-tag: none
x-frame-options: SAMEORIGIN
x-powered-by: PHP/7.1.8
set-cookie: ocawkdp98rhh=fnh8f0asg56puf4e1jbfq7f9g7; path=/nextcloud; HttpOnly
expires: Thu, 19 Nov 1981 08:52:00 GMT
cache-control: no-cache, no-store, must-revalidate
pragma: no-cache
set-cookie: oc_sessionPassphrase=iOp0LnfMGOpv7Pc9%2F0lk88C3eZDfS3620ruffM4qo%2Bs%2BO7ATGpeAtqpYF4tmUeikG38xgFYIsEnOX70tbP9JB3cVxAz9lMkhmrifLqTd5zQ1GDkjmXSeswraTUuNd9LU; path=/nextcloud; secure; HttpOnly
content-security-policy: default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self';connect-src 'self';media-src 'self'
x-frame-options: SAMEORIGIN
set-cookie: nc_sameSiteCookielax=true; path=/nextcloud; httponly;secure; expires=Fri, 31-Dec-2100 23:59:59 GMT; SameSite=lax
set-cookie: nc_sameSiteCookiestrict=true; path=/nextcloud; httponly;secure; expires=Fri, 31-Dec-2100 23:59:59 GMT; SameSite=strict
content-length: 7696
x-content-type-options: nosniff
x-xss-protection: 1; mode=block
x-robots-tag: none
x-download-options: noopen
x-permitted-cross-domain-policies: none
content-type: text/html; charset=UTF-8

with the htbridge tool, I get a B grade for security, because I have not enabled HPKP. Anyway, my Apache configuration uses following settings:

  # this is for nextcloud
  <IfModule mod_headers.c>
      Header always set Strict-Transport-Security "max-age=15768000; includeSubDomains; preload"
      Header always set X-XSS-Protection "1; mode=block"
      Header always set X-Content-Type-Options nosniff
      Header always set X-Robots-Tag none
      Header always set X-Frame-Options SAMEORIGIN
  </IfModule>

And in Nextcloud, I definitely get the setup warnings that the headers are configured wrong. However, if I remove the keyword ‘always’ in my Apache config, Nextcloud does no longer complain, but with the security check I get a straight F. I also checked the .htaccess file in the Nextcloud directory. It has the same contents in it as @MichaIng told.

What should I do?