1

I am trying to setup HSTS for my website but running into some problems regarding HSTS and the use of the www. sub domain. What I would like is for all HTTP and HTTPS traffic to redirect to https://www.example.co.uk.

I have been using the information on the following websites as a guide: https://www.danielmorell.com/blog/how-to-configure-hsts-on-www-and-other-subdomains

The examples on the above websites show the strict-transport-security (STS) header at all the redirect stages.

E.g. http://example.com 301 redirects to https://example.com (STS in header). Then https://example.com redirects to https://www.example.com (STS in header).

However when I try my own domain I only get the STS header on the initial redirect and not the next redirection to the https://www. sub domain.

Examples from my own testing:

  1. http://example.co.uk (301) to https://example.co.uk (STS in header) (301) to https://www.example.co.uk (No STS in header).

  2. http://www.example.co.uk (301) to https://www.example.co.uk (No STS in header).

  3. https://example.co.uk (STS in header) then (301) to https://www.example.co.uk (No STS in header).

  4. https://www.example.co.uk (No STS in header).

Below is a copy of the header response using option 1 above:

http://example.co.uk

HTTP/1.1 301 Moved Permanently
Date: Mon, 04 Feb 2019 18:14:30 GMT
Server: Apache
Location: `https://example.co.uk`/
Content-Length: 237
Content-Type: text/html; charset=iso-8859-1

https://example.co.uk/

HTTP/1.1 301 Moved Permanently
Date: Mon, 04 Feb 2019 18:14:33 GMT
Server: Apache
Strict-Transport-Security: max-age=31557600; includeSubDomains;
Location: https://www.example.co.uk/
Content-Length: 241
Content-Type: text/html; charset=iso-8859-1

https://www.example.co.uk/

HTTP/1.1 200 OK
Date: Mon, 04 Feb 2019 18:14:35 GMT
Server: Apache
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Set-Cookie: PHPSESSID=fkjqaomopnp03uforuptdu3u17; path=/
Transfer-Encoding: chunked
Content-Type: text/html; charset=ISO-8859-1

My website is running on a shared Apache server. I have a valid Let's encrypt cert with CN = example.co.uk.

I have tried the suggestions at: https://webmasters.stackexchange.com/questions/115125/hsts-implementation-when-using-www-tld but it didn't seem to solve my problem.

My .htaccess is shown below:

<if "%{HTTPS} == 'on'">
  Header always set Strict-Transport-Security "max-age=31557600; includeSubDomains;"
</if>

## Base Redirects ##

# Turn on Rewrite Engine
RewriteEngine On

# Redirect to secure HTTPS before changing host
RewriteCond %{HTTP_HOST} !^www\.(.*)$ [NC]
RewriteCond %{https} off  
RewriteRule ^(.*)$ https://example.co.uk/$1 [R=301,L]

# Remove trailing slash from non-filepath urls
RewriteCond %{REQUEST_URI} /(.+)/$
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ https://www.example.co.uk/%1 [R=301,L]

# Include trailing slash on directory 
RewriteCond %{REQUEST_URI} !(.+)/$
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^(.+)$ https://www.example.co.uk/$1/ [R=301,L]

# Force HTTPS and WWW 
RewriteCond %{HTTP_HOST} !^www\.(.*)$ [OR,NC]
RewriteCond %{https} off  
RewriteRule ^(.*)$ https://www.example.co.uk/$1 [R=301,L]

I have tried a couple of my other sub domains and they all send the STS in their response.

So the problem appears to be with the https://www. sub domain despite the directive includeSubDomains being present and I'm at a loss as to why and how to get it working. Could it be a problem with the server settings if so which settings should be checked?

Ross Hodgman
  • 31
  • 1
  • 2
  • `includeSubDomains` has nothing to do with the header being sent or not. It just tells the client (browser) that when it receives such a header it should act as though it had received HSTS headers for all subdomains as well. – AndrolGenhald Feb 06 '19 at 20:04

1 Answers1

1

Answer is paritially from this answer.

RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule .* https://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

# Only set HSTS header if protocol is HTTPS
<if "%{HTTPS} == 'on'">
        Header always set Strict-Transport-Security "max-age=31557600; includeSubDomains;"
</if>

# Remove trailing slash from non-filepath urls
RewriteCond %{REQUEST_URI} /(.+)/$
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ https://www.example.co.uk/%1 [R=301,L]

# Include trailing slash on directory 
RewriteCond %{REQUEST_URI} !(.+)/$
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^(.+)$ https://www.example.co.uk/$1/ [R=301,L]

This should work. I tested it.

  • 1
    thanks for your reply. Unfortunately this failed to fix the issue with the https://www sub domain not giving the STS in it's response. But I found this question: https://stackoverflow.com/questions/32667176/putting-hsts-headers-in-apache-using-htaccess-or-httpd-conf and the answer appears to have solved the issue. I also saw this article https://www.tunetheweb.com/security/http-security-headers/hsts/ and am wondering if the issue is possibly being caused by the config files for my site and that I should ask my host to try the suggestions in the above article. – Ross Hodgman Feb 07 '19 at 18:19