HSTS - The missing link in Transport Layer Security

HTTP Strict Transport Security (HSTS) is a policy mechanism that allows a web server to enforce the use of TLS in a compliant User Agent (UA), such as a web browser. HSTS allows for a more effective implementation of TLS by ensuring all communication takes place over a secure transport layer on the client side. Most notably HSTS mitigates variants of man in the middle (MiTM) attacks where TLS can be stripped out of communications with a server, leaving a user vulnerable to further risk.



In a previous blog I demonstrated using SSLstrip to MiTM SSL and the dangers it posed. Once installed as a MiTM, SSLstrip will connect to a server on behalf of the victim and communicate using HTTPS. The server is satisfied with the secure communication to the attacker who then transparently forwards all data to the victim using HTTP. This is possible because the victim does not enforce the use of TLS and either typed in twitter.com and the browser defaulted to http://, or they were using a bookmark or link that contained http://. Once Twitter receives the request it issues a redirect back to the victim's browser pointing to the https:// URL. Because all of this is done using HTTP the communications are vulnerable to be intercepted and modified by SSLstrip. Crucially, the user receives no warnings during the attack and can't verify if they should be using https://. HSTS mitigates this threat by providing an option to enforce the use of TLS by the browser, which would prevent the user navigating to the site using http://.


Implementing HSTS

In order to implement HSTS a host must declare to a UA that it is a HSTS Host by issuing a HSTS Policy. This is done with the addition of the HTTP response header Strict-Transport-Security: max-age=31536000. The max-age directive is required and can be any value from 0 upwards, which is the number of seconds after receiving the policy that the UA is to treat the host issuing it as a HSTS Host. It's worth noting that a max-age directive value of 0 informs the UA to cease treating the host that issued it as a HSTS Host and to remove all policy. It does not imply an infinite max-age directive value. There is also an optional includeSubDomains directive that can be included at the discretion of the host such as Strict-Transport-Security: max-age=31536000; includeSubDomains. This would, as expected, inform the UA that all subdomains are to be treated as HSTS Hosts also.

Twitter's HSTS Policy


The HSTS response header should only be sent over a secure transport layer but UAs should ignore this header if received over HTTP. This is primarily because an attacker running a MiTM attack could maliciously strip out or inject this header into a HTTP response causing undesired behaviour. This however does present a very slim window of opportunity for an attacker in a targeted attack. Upon a user's very first interaction with Twitter, the browser will have no knowledge of a HSTS Policy for the host. This will result in the first communication taking place over HTTP and not HTTPS. Once Twitter receives the request and replies with a redirect to a HTTPS version of the site, still using HTTP, an attacker could simply effect a MiTM attack against the victim as they would before. The viability of this form of attack however has, overall, been tremendously reduced. The only opportunity the attacker now has, is to be setup and prepared to intercept the very first communication ever with the host, or, wait until the HSTS policy expires after the victim has had no further communication with the host for the duration of the max-age directive.

HSTS Header sent via HTTPS

 No HSTS Header sent via HTTP


Once the user has initiated communications with a host that declares a valid HSTS Policy the UA will consider the host to be a HSTS Host for the duration of max-age and store the policy. During this time the UA will afford the user the following protections.

1. UAs transform insecure URI references to an HSTS Host into secure URI references before dereferencing them.
2. The UA terminates any secure transport connection attempts upon any and all secure transport errors or warnings. source


Point 1 means that once Twitter has been accepted by the UA as a HSTS Host that the UA will replace any reference to http:// with https:// where the host is twitter.com (and it's subdomains if specified) before it sends the request. This includes links found on any webpage that use http://, short cuts or bookmarks that may specify http:// and even user input such as the address bar. Even if http:// is explicitly defined as the protocol of choice the UA will enforce https://.
Point 2 is also fairly important, if not as important as point 1. By terminating the connection as soon as a warning or error message is triggered the UA will prevent the user from clicking through them. This commonly happens when the user does not understand what the message is saying or because they are not concerned about the security of the connection. Many attacks are dependent on the poor manner in which users are informed of potential risk and the poor response from users to this warning. By simply terminating the connection when there is cause for any uncertainty provides the highest possible level of protection to the user. It even stops you accidentally clicking through an error message!

So, once a user has a valid HSTS Policy in place, their request to http://twitter.com should go from something like this:

 Initial request uses HTTP with no HSTS policy enforced


To something like this instead:

 All requests use HTTPS when HSTS is enforced


This can also be verified using the Chrome Developer Tools. Open a new tab, click the Chrome Menu chrome-menu in the top right then select Tools -> Developer Tools and open the network tab. Now navigate to http://twitter.com (you must have visited the site before). You can see the initial request that would have gone to http://twitter.com is not sent and the browser immediately replaces that with a request to https://twitter.com instead.

Request using HTTP is not sent

 HTTP request replaced with HTTPS equivalent


HSTS In Practise

Whilst not yet being widely deployed HSTS has started to make a more widespread appearance since the specification was published in Nov 2012. Below you can see that both Twitter and Facebook have the HSTS response header set, though Facebook doesn't appear to have a very long max-age value.

Twitter's HSTS Policy

Facebook's HSTS Policy


Out of interest I decided to check a selection of websites for high street banks and see if any had yet implemented a HSTS Policy. Having checked Barlcays, Halifax, HSBC, Nationwide, Natwest, RBS, Santander and Yorkshire Bank I was disappointed to find that none had yet implemented a HSTS Policy and some of them even have a dedicated online banking domain name.


Preloaded HSTS

It is also possible for a browser to ship with a preloaded list of HSTS Hosts. The Chrome and Firefox browsers both feature a built in list of sites that will always be treated as HSTS Hosts regardless of the presence of the HSTS response header. Websites can opt in to be included in the list of preloaded hosts and you can view the Chromium Source to see all the hosts already included. For sites preloaded in the browser there is no state where communications will take place that do not travel on a secure transport layer. Be that the initial communication, the first communication after wiping the local cache or any communication after a policy would have expired, the user cannot exchange data using HTTP. The browser will afford the protection of HSTS for the applicable hosts at all times. Unfortunately this solution isn't really scalable considering the sheer potential for the number of sites that could be included. That said, if all financial institutions, government sites, social networks and any other potentially large target applied to be included, they could mitigate a substantial amount of risk.



HSTS has been a highly anticipated and a much needed solution to the problems of HTTP being the default protocol for a UA and the lack of an ability for a host to reliably enforce secure communications. For any site that issues permanent redirects to HTTPS the addition of the HSTS response header is a much safer way of enforcing secure communications for compliant UAs. By preventing the UA from sending even the very first request via HTTP, HSTS removes the only opportunity a MiTM has to gain a foothold in a secure transport layer.

Read More: Manually Enforcing HSTS in Google Chrome - Issuing HSTS Policy in PHP - How HSTS Could Have Largely Mitigated the Polish DNS Hijacking Attack - Setting up HSTS in NginX - HSTS Preloading



Short URL: https://scotthel.me/hsts

Author image
About Scott
Researcher, blogger and international speaker. I'm the creator of report-uri.io and securityheaders.io, free tools to help improve online security.