A Warning About HSTS

HTTP Strict Transport Security (HSTS) is a web security policy that allows web masters to enforce HTTPS on their websites. The main aim is to protect against down grade attacks whereby browsers could be tricked into connecting over HTTP even if HTTPS was available and meant to be used.

HSTS is implemented via an HTTP header that specifies that all content on the page should be loaded via HTTPS otherwise it should be blocked. The header also specifies how long this directive should be cached for by the browser.

It is therefore highly advised to enable HSTS only when you can guarantee that all the assets of your website are available over HTTPS, otherwise your users may experience errors as the website would stop functioning correctly.

HSTS technically only applies to your domain or sub domains so I was not too sure what the browser behaviour would be with assets hosted on third party domains. By default, if a connection is made over HTTPS and a third party asset is loaded over HTTP, a warning is shown in the browser to the end user, usually by displaying a yellow/orange locket. But what happens if HSTS is enabled?

HSTS

The image above shows some testing I performed with the Google Chrome browser (version 44.0.2403.157 m). The diagram displays what happens to the address bar in six different cases with third party assets. The first three cases on the left show the address bar without HSTS enabled and the three on the right with HSTS enabled. Each case shows what happens when we have:

  1. a connection without errors (everything loads over HTTPS);
  2. a connection with external mixed content (JavaScript file);
  3. a connection with external mixed content (image file).

As we can see the browser behaviour with HSTS is not exactly what you would expect. In particular, the browsers shows a green locket when a JavaScript link is over HTTP even if HSTS is enabled! The browser is in fact blocking and avoiding to load JavaScript files over HTTP all together. This actually makes sense as the page is not potentially compromised even if some assets are missing.

The behaviour, however, is different if instead of a third party JavaScript file we have an image. An image hosted on an external domain is in fact still loaded even with HSTS enabled and the browser bar will show a yellow locket. I personally find this confusing and I don't understand the need for the exception.