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

hallo everybody… and happy 2017.
This is my first question about nextcloud.

I just installed v11 through CPanel/Softaculous but I have a little problem.

I get this warning when I connect through https in the admin panel:
The “Strict-Transport-Security” HTTP header is not configured to at least “15552000” seconds. For enhanced security we recommend enabling HSTS as described in our security tips.

I have apache with mod_headers.c enabled and I have added this line:
Header set Strict-Transport-Security "max-age=15552000; includeSubDomains; preload"
at the end of .htaccess located in www.mysite[dot]com/nextcloud (that is the .htaccess created by nextcloud)

If I request www[dot]mysite[dot]com/nextcloud/index[dot]php page the header is not influenced by this directive.
BUT if I request www[dot]mysite[dot]com/nextcloud/test[dot]html (a file I created for testing purposes) the header contains the modification.

Where is the problem?
Can you help me?

P.S.
I checked the header with firebugs and also with the command “curl -I https://www[dot]mysite[dot]com/nextcloud”

1 Like

Does .htaccess work?

<Directory /var/www/>
    Options Indexes FollowSymLinks
    AllowOverride All
    Require all granted
</Directory>

Take a look at your Apache config

<IfModule mod_headers.c>
    Header always add Strict-Transport-Security "max-age=15768000; includeSubDomains; preload"
</IfModule>

and test with

http://web-sniffer.net/

1 Like

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