HTTP Strict Transport Security
HTTP Strict Transport Security
As the name suggests, HSTS is a mechanism that forces browsers to use a secure web connection.
In fact, we can call HSTS the ‘missing link’ in the secure web connection chain. Why?
With end-to-end encryption, SSL lays the foundation for a secure and authorized connection. In an ideal SSL implementation, we can ensure that the data is not altered or monitored by a third party during transmission, or verify that the person we’re communicating with is the intended recipient of the traffic.
I say ‘ideal’ because the partial implementations that some web applications use, such as secure connections only in login and checkout pages, pose a huge threat. The risks that arise with partial implementations are covered in detail in HTTP Cookie Hijacking in the Wild (DEF CON 24 conference).
If we do not force all our pages to be transmitted over a secure connection, attackers can easily forward their targets to surf the web on the unsafe connection or convert the HTTPS traffic to HTTP by launching MITM attacks (such as SSL Strip).
That’s not all. Expired or invalid certificates are highly threatening to your secure connections. Your website’s reputation will also be damaged if your users are confronted with such easily preventable problems.
Is There Any Way to Further Improve HTTPS Protection on Your Website?
If you want to take full advantage of SSL, you have to convert all HTTP requests to HTTPS, and load all images, scripts, style files and other files over a secure connection. You also have to go as far as preventing the user from dismissing certificate errors.
Doing all this manually is rather difficult, especially in case of a certificate error when you have to prevent the user from accessing your website.
Thankfully, the HSTS specification published in November 2012 is the solution to this problem. All we have to do is to set a security header (Strict-Transport-Security) on our web page response. With this security header we can direct our browser to:
- Convert all requests to an HTTPS connection
- In case of a certificate related error such as an expired certificate, prevent the user from browsing the website anyway
- Cache this setting for a specified amount of time
Strict Transport Security Header Example
Here is an example of how to use this header:
max-age: This directive allows us to specify the amount of time (in seconds) that the content of the header will be stored in the browser cache.
There are two more significant specifications in the HSTS implementation: the includeSubdomains parameter and the preload parameter. We can enforce the same strict, secure connection on all the subdomains of the website using the includeSubdomains parameter.
First Request and Preload
We can only set the HSTS header over a secure connection. Just like Public Key Pinning (which is another HTTPS security header), HSTS is based on Trust on First Use (TOFU). This means that we have to manually redirect the users, on their first HTTP request, to the HTTPS version of our website. In its response, there will be an HSTS header, meaning that the browsers will store it in their cache. The next time an unsafe (HTTP) connection arises, it will automatically be redirected to a secure connection.
The obvious question is: could a hacker override this first HTTP request with a MiTM attack?
Unfortunately, the answer is yes. However, this time, the HSTS preload list comes to the rescue.
We need to add the preload directive to our HSTS header for the website to be eligible for inclusion in the HSTS preload list. The browser will check whether or not a site is included in the list and will simply refuse to load it over an insecure connection.
Additional Requirements for the HSTS Preload List
Adding our website to the HSTS Preload List has some further requirements:
- You need to serve a valid certificate.
- You must redirect from HTTP to HTTPS on the same host, meaning that the HTTPS traffic for example.com should go through example.com (not through any other domain such as secure.example.com).
- You must support HTTPS for all subdomains, particularly the www subdomain.
- You have to set the following values for the HSTS header:
- The max-age must be at least 31536000 seconds (1 year)
- The includeSubDomains and preload directives must be specified