2

I intend to HSTS preload a site, and have see the following header. No problem. It works.

Header set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" env=HTTPS

A condition of HSTS preloading is that I also redirect all HTTP traffic to HTTPS. To do so, I'm using the following instruction:

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

This too, works. If it test my root domain (example.com) at hstspreload.org, I see green and can add my domain to the preload list. This is great, with one caveat.

I want load my site at https://www.example.com, not https://example.com. This should be easy enough:

RewriteCond %{HTTPS} on
RewriteCond %{HTTP_HOST} ^example.com [NC]
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

If it go back to hstspreload.org, I receive the following error:

Response error: No HSTS header is present on the response.

When I enter any subdomain into the hstspreload.org bar, I see green. It's only on the root domain where I receive the error, because, it seems, the root domain is not sending the HSTS header anymore. However, it's a condition of preloading that the root domain must send the header.

I did my homework and searched. I read this post from a couple years ago, but my question isn't about SEO. And, two redirects -- one from HTTP to HTTPS and one from to -- are okay with Google.

I'm reasonably confident that I can have HSTS preload and WWW redirection. Troyhunt.com redirects to HTTPS and then WWW. The root domain also validates on hstspreload.org. However, I believe he uses IIS, so asking him what do on Apache would help me little.

I'll be grateful for any ideas. I'm trying, but I'm a bit of a beginner. Thank you!

carmi
  • 41
  • 4

2 Answers2

2

Got it! All your feedback was spot-on. I never would've gotten this. THANK YOU, Barry!!!

Here are my working instructions. First, all traffic is redirected to HTTPS. Then, if the connection is HTTPS, the HSTS header gets sent. As you implied, the env=HTTPS wasn't really the right approach. Then, the redirect to WWW happens.

RewriteEngine On

# Redirect to HTTPS
RewriteCond %{HTTPS} off
RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

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

# Redirect to WWW
RewriteCond %{HTTPS} off [OR,NC]
RewriteCond %{HTTP_HOST} ^example.com [NC]
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
carmi
  • 41
  • 4
  • This is the proper one as noted on https://hstspreload.org/ On home.pl remove wrap, same if no header is visible. Be sure that is before any other redirect. If second is added then use that one as only one. – Patryk Sep 03 '20 at 21:30
0

To include headers on redirects you need to add the always attribute:

Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" env=HTTPS

I am also not sure when env=HTTPS is set - it might be set after the redirect happens so above will not work?

To be honest I usually put the HSTS setting in the SSL vhost so it only applies to HTTPS connections rather than try to get clever using env=HTTPS.

If you have several SSL vhosts then this allows you to have different HSTS - for example to not have includeSubDomains on the base domain, but do have it on the www domain. This is useful if you have not yet migrated non-www domains to HTTPS. However for preloading you must have includeSubDomains on both base and www domain so this probably doesn’t apply to you.

Barry Pollard
  • 40,655
  • 7
  • 76
  • 92
  • Thanks, Barry! Unfortunately, it produced the same result. That said, I think I'm closer. I did some reading as a result of you informing me about the `always` attribute. That'll definitely be required as part of the solution. – carmi Mar 15 '19 at 23:39
  • Are you definitely setting the header before you do the redirect and not after? I updated my answer with an alternative (and IMHO better) way of setting this. – Barry Pollard Mar 16 '19 at 09:24
  • I have the header as my first instruction in my htaccess file, before `RewriteEngine On` for the redirects. To your point, the header appears to be getting set after the redirect. I'm using a managed host and don't have access to the SSL vhost. I'll ask. Thanks again Barry! – carmi Mar 17 '19 at 11:10