"Strict-Transport-Security" HTTP header (HSTS)

Hallo, and sorry for my late answer (a broken leg gave me some problems).

I don’t have access to apache settings, but they should be OK and .htaccess works (I.E. I have tried the option Indexes).

and I added these line:
Header set Strict-Transport-Security "max-age=15552000; includeSubDomains; preload"
at the end of /public_html/nextcloud/.htaccess
not nested in any conditional statement to be sure it is used.

Giacomo

1 Like

Could you add an “always” to your Header directive?

We have “Header always add...” and “Header set...” here and I have “Header always set...” in my config. So I checked about it: https://httpd.apache.org/docs/current/mod/mod_headers.html

According to this I would recommend my solution: “Header always set...”.

The file …/nextcloud/.htaccess has been created by Nextcloud but if I make any change in that file it seems to be ignored (even if I write below the line #### DO NOT CHANGE ANYTHING ABOVE THIS LINE #### )

In every other folder, the .htaccess file works fine and I can set whatever variable.

Any idea why that .htaccess file is ignored?

Thanks, in advace for your help.

Giacomo

AllowOverride All is set in your nextcloud Directory directive/vhost?

I have not access to apache configuration, but I think yes, AllowOverride All is set.

For example, I can set options like INDEXES and I can even set variables for the header, for whatever directory.
I can create any new folder and .htaccess works perfectly in that new folder… everywhere but the folder where I installed Nexcloud.

I created a test folder, with the following .htaccess:

Headers variable and Indexes work perfectly (files are not shown).

Giacomo

On my system I am using FreeNAS so I just added this to the .htaccess file in
/usr/pbi/nextcloud-amd64/www/nextcloud and it worked great.

Thanks for the tip!

1 Like

I know this is an old post but for future reference, instead of adding the line to .htaccess according to this article in Nextcloud documentation you should add it to your Apache virtual host like so:

< VirtualHost *:443>
ServerName cloud.yourdomain.com
< IfModule mod_headers.c>
Header always set Strict-Transport-Security “max-age=15552000; includeSubDomains”
< /IfModule>
< /VirtualHost>

Which “Virtual host file” ?
I tried to add this in /etc/apache2/sites-enabled/default-ssl.conf
And the mod_headers is enabled.
But I still get the warning in the Admin page.

Default-ssl.conf is for the default website,
You need to modify it on the nextcloud ssl conf file.

You need also to restart apache2 after modifing the file

1 Like

Thanks for your reply.
So, I installed nextcloud on a fresh install of Ununtu 16.04.
It is dedicated to nextcloud with only 1 “Virtual Host”

I am redirecting the web root to the nextcloud folder and it is secure/encrypted with let’s encrypt.

I tried to add these lines in default-ssl.conf first and then tried nextcloud.conf.
I even re-booted the server everytime and I still get the “Strict-Transport-Security” warning.

I my case, which file I am supposed to modify?

Thanks

I finally got it. It was the nextcloud.conf that I needed to modify. But in the instructions it says to add:
<VirtualHost *:443>
ServerName cloud.nextcloud.com
< IfModule mod_headers.c>
Header always set Strict-Transport-Security “max-age=15552000; includeSubDomains”
< /IfModule>
< /VirtualHost>

And this did not work.

What worked was to paste it without the VirtualHost tag like so:

ServerName cloud.nextcloud.com
< IfModule mod_headers.c>
Header always set Strict-Transport-Security “max-age=15552000; includeSubDomains”
< /IfModule>

2 Likes

Hello,

I have the following error on my nextcloud 14 instalation and i’m using also let’s encrypt :

There are some warnings regarding your setup.

  • The “Strict-Transport-Security” HTTP header is not set to at least “15552000” seconds. For enhanced security, it is recommended to enable HSTS as described in the security tips :arrow_upper_right:.

I tried to add this to my nextcloud vhost :

< IfModule mod_headers.c>
Header always set Strict-Transport-Security “max-age=15552000; includeSubDomains”
< /IfModule>

but the error it’s still there

I’m using ubuntu 18.04 and i have setup a apache proxy and also i’m using CloudFlare dns
what could be the issue ?

Regards,
Dimostin

Apache module not loaded?
a2enmod headers

1 Like

i think the “headers” module it’s loaded i tried this :

" # apachectl -t -D DUMP_MODULES | grep headers
headers_module (shared) "

" # a2enmod headers
Module headers already enabled "

Please verify that this header needs to be set inside the https/443 vhost.

Also try to remove the condition. Syntax looks good, but by this you can verify that the header is set correctly. Apache would throw an error on start-up if something is wrong.

You can also test if the header is set via curl:

curl -s -D- https://your.domain.org/nextcloud | grep Strict

Chrome can also check this: chrome://net-internals#hsts

i have no output for this command : “curl -s -D- https://your.domain.org/nextcloud | grep Strict”

this is my vhost for nextcloud:

<IfModule mod_ssl.c>
<VirtualHost *:443>

        ServerName cloud.mydomain.org
        ServerAdmin webmaster@localhost

<IfModule mod_headers.c>
Header always set Strict-Transport-Security "max-age=15552000; includeSubDomains"
Header always set Referrer-Policy "no-referrer"
Header always set Referrer-Policy "no-referrer-when-downgrade"
Header always set Referrer-Policy "strict-origin"
Header always set Referrer-Policy "strict-origin-when-cross-origin"

# Prevent MIME based attacks
Header set X-Content-Type-Options "nosniff"
</IfModule>

SSLEngine on
SSLCipherSuite EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH
SSLProtocol All -SSLv2 -SSLv3 -TLSv1 -TLSv1.1
SSLHonorCipherOrder On

        ProxyPreserveHost On
        ProxyPass / http://192.168.1.10:80/
        ProxyPassReverse / http://192.168.1.10:80/

        ErrorLog ${APACHE_LOG_DIR}/cloud.mydomain.org-error.log
        CustomLog ${APACHE_LOG_DIR}/cloud.mydomain.org-access.log combined

SSLCertificateFile /etc/letsencrypt/live/cloud.mydomain.org/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/cloud.mydomain.org/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
</VirtualHost>
</IfModule>

I assume you replaced https://your.domain.org/nextcloud with the actual domain/path to your Nextcloud :wink: .

Please try just: curl -D- https://your.domain.org/nextcloud
It should output all headers received from server to terminal.

In my case it looks like this:

HTTP/1.1 302 Found
Date: Tue, 09 Oct 2018 13:20:20 GMT
Server: Apache
Strict-Transport-Security: max-age=15552000; includeSubDomains; preload
Location: /nextcloud/
X-Content-Type-Options: nosniff
X-Frame-Options: sameorigin
X-XSS-Protection: 1; mode=block
Content-Security-Policy: default-src 'self' 'unsafe-inline' 'unsafe-eval';
X-Robots-Tag: none
Referrer-Policy: no-referrer
X-Download-Options: noopen
X-Permitted-Cross-Domain-Policies: none
Content-Length: 0
Content-Type: text/html; charset=UTF-8

You set:

Header always set Referrer-Policy "no-referrer"
Header always set Referrer-Policy "no-referrer-when-downgrade"
Header always set Referrer-Policy "strict-origin"
Header always set Referrer-Policy "strict-origin-when-cross-origin"

If I am not mistaken, the second value set to the same header will overwrite the first. You can use Header always add to add an additional value, but not sure if this is handled (as you want it). I would decide if you want the stricter rule or the less strict (the second in your cases) and only apply the one.
Your current case might be also the reason for errors, not sure.
Everything can be tested via above curl command.


So I would assume you replace:

<IfModule mod_headers.c>
Header always set Strict-Transport-Security "max-age=15552000; includeSubDomains"
Header always set Referrer-Policy "no-referrer"
Header always set Referrer-Policy "no-referrer-when-downgrade"
Header always set Referrer-Policy "strict-origin"
Header always set Referrer-Policy "strict-origin-when-cross-origin"

# Prevent MIME based attacks
Header set X-Content-Type-Options "nosniff"
</IfModule>

by

Header always set Strict-Transport-Security "max-age=15552000; includeSubDomains"
Header always set Referrer-Policy "no-referrer"
Header always set Referrer-Policy "strict-origin"

# Prevent MIME based attacks
Header set X-Content-Type-Options "nosniff"

And recheck the received headers via: curl -D- https://your.domain.org/nextcloud

so my vhost config looks like this now:

<IfModule mod_ssl.c>
<VirtualHost *:443>

        ServerName cloud.mydomain.org
        ServerAdmin webmaster@localhost

<IfModule mod_headers.c>
Header always set Strict-Transport-Security "max-age=15552000; includeSubDomains"
Header always set Referrer-Policy "no-referrer"
Header always set Referrer-Policy "strict-origin"

# Prevent MIME based attacks
Header set X-Content-Type-Options "nosniff"
</IfModule>

SSLEngine on
SSLCipherSuite EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH
SSLProtocol All -SSLv2 -SSLv3 -TLSv1 -TLSv1.1
SSLHonorCipherOrder On

        ProxyPreserveHost On
        ProxyPass / http://192.168.1.10:80/
        ProxyPassReverse / http://192.168.1.10:80/

        ErrorLog ${APACHE_LOG_DIR}/cloud.mydomain.org-error.log
        CustomLog ${APACHE_LOG_DIR}/cloud.mydomain.org-access.log combined

SSLCertificateFile /etc/letsencrypt/live/cloud.mydomain.org/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/cloud.mydomain.org/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
</VirtualHost>
</IfModule>

and after i issued this command " curl -D- https://cloud.domain.com " i have the following output:

# curl -s -D- https://cloud.mydomain.com
HTTP/2 302
date: Tue, 09 Oct 2018 13:35:02 GMT
content-type: text/html; charset=UTF-8
set-cookie: __cfduid=d7c13864ec1f2ffd28cf91ffb2408b8531539092102; expires=Wed, 09-Oct-19 13:35:02 GMT; path=/; domain=.mydomain.com; HttpOnly; Secure
strict-transport-security: max-age=0; includeSubDomains; preload
referrer-policy: strict-origin
expires: Thu, 19 Nov 1981 08:52:00 GMT
cache-control: no-store, no-cache, must-revalidate
pragma: no-cache
content-security-policy: default-src 'self'; script-src 'self' 'unsafe-eval' 'nonce-MjBLcFFxdERXRmpQejhhek1LcUZWQm9pYXhJNlJzMjN1Qnp5dVpaUkJHOD06bGlQSURPb3BhanFGalpUcFo4bTNaM0owQ1dkTEJiWGU3bSt3MGVZWWJCYz0='; 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
location: https://cloud.mydomain.com/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
set-cookie: ocz9mx9tsb1o=6dmprkt1pl2jank5cancgdbs4g; path=/; secure; HttpOnly
set-cookie: oc_sessionPassphrase=Xmw3IYAhQuePaWGmzCfW7JGf%2BNIAi%2F56KWli7SuwcWyF87KB1V6jRAiCjPOU5QP3RhuwywmRp4Pe0SMEDPiEjQldBBVSGJb8IdZoLt2isiBxiGHBykugknhqQiUwGDOd; path=/; secure; HttpOnly
set-cookie: __Host-nc_sameSiteCookielax=true; path=/; httponly;secure; expires=Fri, 31-Dec-2100 23:59:59 GMT; SameSite=lax
set-cookie: __Host-nc_sameSiteCookiestrict=true; path=/; httponly;secure; expires=Fri, 31-Dec-2100 23:59:59 GMT; SameSite=strict
expect-ct: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
server: cloudflare

Whoopsie, mixed up
Header always set Referrer-Policy "strict-origin"
with
Header always set X-Frame-Options "sameorigin"

referrer-policy: strict-origin

As you can see, the second header line overrides the first.
Please try to remove Header always set Referrer-Policy "strict-origin" line as well to be most strict.

Check out the result of the different directives: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy#Directives


But this shows, that the other headers are set as expected, just HSTS somehow wrong:

strict-transport-security: max-age=0; includeSubDomains; preload

Hmm strange, as my config line looks exactly the same… and where is the preload option coming from?..

Certbot places an own security config file that is loaded after you set your headers. See in your config at the bottom: Include /etc/letsencrypt/options-ssl-apache.conf

Please check this file, as perhaps it overrides your HSTS.

And again, for debugging please try as well to remove (or comment out) <IfModule mod_headers.c> and </IfModule> around the header section.

preload does only work if the domain is added to the preload-list:

https://hstspreload.org/

But be careful and know what you are doing.

1 Like