The HTTP Strict-Transport-Security (HSTS) header can be used to increase the security of a website. In this post we’ll discuss how it works, why it’s important and why you should consider using the HSTS header.
The problem without HSTS
As you may know, the Hypertext Transfer Protocol (HTTP) is a cleartext protocol. This means that all data transferred using this protocol can be read by someone with access to the network, as data is not encrypted when transmitted between client and server.
You may also know that this problem is resolved by using HTTPS, which essentially encrypts the data transmitted between the client and server.
Many websites respond on both HTTP and HTTPS, typically the web server will be configured to perform a 301 redirect for HTTP requests to the HTTPS equivalent, ensuring that further communications are secure.
There is a problem with this, however. Unless a visitor to the website in question purposefully enters the HTTPS version of the URL, by default if they just enter the domain name into the browser the first request will be over cleartext HTTP.
Therein lies the problem, if this first request is intercepted by a Man-in-the-middle (MITM) style attack, the client has no assurance that they are interacting with a legitimate server. For example, at this point the MITM could serve a duplicate copy of the website from their own server and wait for the victim to enter their credentials.
How HSTS tries to help
This is where the HSTS header tries to fix the situation. The HSTS header can be served out by the web server (such as Apache or Nginx) along with the other usual headers. Web browsers which support HSTS will receive this header and send all future requests using HTTPS. Even if you manually enter a URL using HTTP, the browser will ignore this and change it to HTTPS before anything has been transmitted over the network.
This sounds great, but there’s still a slight problem here. The web browser will not start behaving in this manner until it first receives the HSTS header from the web server. This means that the first time a user ever browses to a website using HSTS, their browser is not yet aware of the presence of the HSTS header, so this first initial request could still be intercepted.
Additionally, the HSTS header is only valid for the period of time defined within the header. It is generally recommended that this be set to at least 6 months, however this does mean that it is possible for the first request after header expiry to be sent over cleartext HTTP.
HSTS Preload saves the day
These small shortcomings are resolved by using HSTS preload. HSTS preload is essentially a list of all domains that are known to use HSTS. Periodically, this list is updated and the flat file is added into individual web browsers when they are updated. As a result, it can take some time before your domain gets added successfully to the HSTS preload list, it took around 2 months for this domain to be added.
This way the web browser is essentially hard coded to know all HSTS supported domains, so that any time a request to a HSTS domain is made it will be sent over HTTPS straight away without the requirement of first seeing the HSTS header from the destination web server. Setting up preload requires the HSTS header to be modified to contain the includeSubdomains and preload directives.
The preload directive is set in the HSTS header on the web server, once all requirements for preload have been configured you submit your domain to the HSTS preload list.
By default redirecting HTTP requests to HTTPS leaves the possibility for a MITM style attack to intercept the initial request. The HTTP Strict-Transport-Security (HSTS) header attempts to resolve this, once a supported web browser sees the HSTS header it knows that the website has been configured to use HTTPS and will send all future requests over HTTPS rather than HTTP.
This still has the small issue of not working for the first request, it will only start working once the web browser sees the HSTS header for the first time. Additionally the HSTS header is only valid for the period of time defined in the header.
This final shortcoming is resolved by adding the domain to the HSTS preload list, although it takes quite some time to implement, it ensures that supported web browsers will be aware that the website should be accessed over HTTPS, forcing the browser to direct all requests over HTTPS and never use HTTP.