Matthew James
21/06/2019

I recently discovered HTTP Strict Transport Security or HSTS. It's been around forever and I am a little sad that I didn't know about it but also worried that I never came across it until now. The reason not knowing about HSTS is so worrying is because it is literally the first thing that the browser actually does when you attempt to visit any page - paint me humbled.

HSTS is basically a giant local look-up table that contains all the websites that should be auto-redirected from HTTP to HTTPS. The HSTS "look-up table" is pre-loaded by the browser out of the box, but individual sites can also tell browsers to add their URL to the browser's HSTS "look-up table". After a site has been added to a browsers HSTS "look-up table" then all future communication with that webserver will be done over HTTPS. Do note that all future requests to the site over HTTP are converted to HTTPS inside the BROWSER, no initial (or subsequent) request to the webserver will be made over HTTP.

At this point I thought the feature was neat but wasn't exactly impressed. I could accomplish the same effect by deploying the following code into a Web.config file:

<rule name="HTTP to HTTPS redirect" stopProcessing="true">
<match url="(.*)" />
<conditions>
<add input="{HTTPS}" pattern="off" ignoreCase="true" />
<add input="{HTTP_HOST}" pattern="localhost" negate="true" />
</conditions>
<action type="Redirect" url="https://{HTTP_HOST}/{R:1}" redirectType="Permanent" />
</rule>

That would create a regex based URL redirect that intercepts all HTTP requests and redirects them to HTTPS. Not only that but the redirectType="Permanent" means that the redirection type would be a 301 Moved Permanently. By default the 301 response is cacheable by browsers unless indicated otherwise. This means that, just like the HSTS, all future communication with the webserver will be done over HTTPS. So what's the big deal? Unlike a cached redirection a HSTS 307 redirection is generally harder to remove from the browser. A simple removal of the browser cache won't remove HSTS redirect but will remove a cached 301 redirection.

There are ways to remove HSTS from the browser, however outside of testing I can't think of a reason to. As stated previously the HSTS can be pre-loaded into the browser completely removing the very first redirect that a user would normally make. It's also super easy to get added to that list, whether or not the browsers update their lists in a timely matter is up to the vendor. Luckily Chromium and Gecko based browsers seem to have an active interest in HSTS. HSTS implementation can be done in parallel with any existing IIS URL rewrites, and to remain compliant with the HSTS standard you'll need to use both. The RFC 6797 standard states that HSTS host server must only request to be added to the browser's HSTS "look-up table" over HTTPS:

5.1. HSTS Host Declaration An HTTP host declares itself an HSTS Host by issuing to UAs an HSTS Policy, which is represented by and conveyed via the Strict-Transport-Security HTTP response header field over secure transport (e.g., TLS).

This means that you'll need to make use of that IIS URL rewrite to HTTPS before you can tell the client browser to use HSTS. If you're lucky enough to be on IIS 10.0 on Windows 1709 or later then you can utilise the fancy new <hsts> element. If you're running IIS 7+ on Windows Server 2016 or earlier then you can do something similar to this:

<system.webServer>
<rewrite>
<outboundRules>
<rule name="Add Strict-Transport-Security when HTTPS" enabled="true">
<match serverVariable="RESPONSE_Strict_Transport_Security" pattern=".*" />
<conditions>
<add input="{HTTPS}" pattern="on" ignoreCase="true" />
</conditions>
<action type="Rewrite" value="max-age=31536000; includeSubDomains; preload" />
</rule>
</outboundRules>
</rewrite>
</system.webServer>

This snippet is based off Scott Hanselman's code, which itself is based off a Stack Overflow answer. The main change that I have added is the addition of the ; includeSubDomains; preload directives to the end of the returned value. These are considered best practice as they offer improved security. The includeSubDomains directive signals that the HSTS Policy applies to this HSTS Host as well as any subdomains of the host's domain name. This means that the site "example.com" (HSTS Host) is affected as well as "www.example.com" and "other.example.com" (subdomains). While the preload directive isn't located in the RFC 6797 standard, it is required if you plan on being added to the HSTS preload list.

After everything is said and done this work merits more than just added security and faster load times, it also affects SEO rankings. All of this is secondary to the fact that this is the very first thing that a web browser does and I'd never even heard of it. Here's to constantly learning more.