HTTP Strict Transport Security (HSTS)

Every programmer heard about HTTPS as a security layer for HTTP protocol. But HTTPS is not the only security purpose for the most popular web protocol. Another one, known as HSTS, exists too.

Data Engineering Design Patterns

Looking for a book that defines and solves most common data engineering problems? I'm currently writing one on that topic and the first chapters are already available in 👉 Early Release on the O'Reilly platform

I also help solve your data engineering problems 👉 📩

In this article we'll discover what does HSTS acronym mean. In its first part, we'll see the theoretical side of this protection by approaching the definition and working mode. At the second part, we'll focus on practical aspect of HSTS by trying to implement it in Apache web server.

In this article we'll discover what does HSTS acronym mean. In its first part, we'll see the theoretical side of this protection by approaching the definition and working mode. At the second part, we'll focus on practical aspect of HSTS by trying to implement it in Apache web server.

What is HSTS ?

The acronym HSTS means HTTP Strict Transport Security. It's a security policy, introduced at the end of 2012 with the goal to strengthen the protection over network security fails. This policy consists on forcing browser to use HTTPS website version over HTTP version. Now, event if you put website's address without protocol, the browser will know that the website should pass through secured HTTPS protocol. How does browser know about it ? It analyses the responses headers and if they contain a line about HSTS, the browser considers that it must pass through HTTPS.

Against which dangers should protect HSTS ? First of all, man-in-the-middle attacks should be counteract with more facility thanks to HSTS. An attacker using some of freely available sniffing tools can easily intercept user's sensitive data as session cookies. Man-in-the-middle vulnerability can occur for example, when we use non-protected networks.

Even if the user navigates over HTTPS almost all the time, his one call to insecure resource (HTTP) suffices to compromise global website security policy. For example, we can, by mistake, put a hard link to an image hosted in the same domain but under HTTP and not HTTPS. HSTS helps to protect against this type of mistakes, known as mixed content issues too.

But HSTS isn't a miraculous cure against all of client side vulnerabilities. For example, it can't help to protect against phishing because it doesn't permit to distinguish a fake phishing page and a real victimized page. Another issue not covered by HSTS is browser vulnerability. HSTS is based on browser configuration and user's OS security policy which protects browser session. If some of them are compromised, HSTS won't be able to detect the security failure and will proceed as this failure doesn't exist.

How does HTTP Strict Transport Security work ?

Every time when a browser detects presence of HSTS specified header, Strict-Transport-Security, it knows that every resource loaded for website containing it, must be loaded over HTTPS. HSTS policy is more important that another ways of processing URLs by the browser. For example, event if the user puts an address in HTTP in location bar, browser will transfer this request into HTTPS response.

The browser stores every HSTS domain locally. This local cache is managed by every website separately (in Chromium you can access it through chrome://net-internals/#hsts). The modification is done when the Strict-Transport-Security header changes one of its values (lifetime or subdomains applicability). HSTS can be applied to domain with or without its subdomains. This configuration is represented by header's directive includeSubDomains. As HSTS is a protection in the client side, the Strict-Transport-Security header needs to be send in the response.

When the browser knows that some domains can be launched only over HTTPS protocol, it makes the redirection before starting to treat initial request. Incomprehensible ? Imagine that you put into your browser a website address ( that is registered in browser HSTS registry. You push on "enter". Now the browser, instead of trying to reach HTTP version of the website, will rewrite the address by prefixing it with https:// and redirecting you into this new address.

Notice only that it works only after user received a header in HTTPS.

Install HTTP Strict Transport Security

We'll try to install HSTS in Apache web server. As we saw previously, to implement it, we need just to add new header in every response send by the server. To accomplish that in Apache, we have to add this directive into host's configuration file :

LoadModule headers_module modules/
<VirtualHost *:443>
      # Use HTTP Strict Transport Security to force client to use secure connections only
      Header always set Strict-Transport-Security "max-age=120; includeSubDomains"
The HSTS can be applied only to HTTPS virtual hosts. The headers send over HTTP are ignored. According to the HSTS reference, if you're testing HSTS with self-signed certificate, for example generated by OpenSSL, this configuration won't work without supplementary operations. To make it work, you must create SSL Certificate Authority and install Root Certificate in your browser (for example in Chromium's "Manage certificates"). You can follow given steps to do that with a short explanation before everyone:
# 1) Create private root key
bartosz@bartosz-K70ID:~$ sudo openssl genrsa -out /home/bartosz/ssl/key/rootCA.key 2048

# 2) Self sign private root key
bartosz@bartosz-K70ID:~$ sudo openssl req -x509 -new -nodes -key /home/bartosz/ssl/key/rootCA.key -days 1024 -out /home/bartosz/ssl/certificate/rootCA.pem
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
Next you must put this configuration into HTTPS virtualhost of your website:
SSLEngine on
SSLCertificateFile /home/bartosz/ssl/certificate/rootCA.pem
SSLCertificateKeyFile /home/bartosz/ssl/key/rootCA.key
And the final thing to do is to add generated rootCA.pem certificate into authorities known by your browser. For Chromium you can put this chrome://settings/certificates into your address bar, click on "Authorities" tab and import created rootCA.pem file. After this setup, we can pass to install HSTS. The HSTS configuration takes two parameters, max-age and includeSubDomains. The first one determines the length (in seconds) in which the browser will store this entry in HSTS registry. If we put 0 instead of positive number, the browser will cease to treat the hosts as known HSTS and will allow the insecure connections. In our case, the entry will be cached for 2 minutes (120 seconds). The includeSubDomains directive marks if a HSTS entry should concern domain and subdomains. Its absence signifies that browser will regard only the main domain. If it's specified, the subdomains will be taken in consideration too. Now we understand how to install HSTS. So, let's try it into our localhost domain. Start by typing localhost into location bar in your browser. The Strict-Transport-Security is present but the site is available in HTTP. Yes, it's normal. HSTS policy applies only if you visit the website over HTTPS. At this moment STS response header is valid for the browser and only at this moment, the browser can register new the HSTS entry. So, for see HSTS working, we need to start the test by accessing https://localhost and, after that, http://localhost. If your certificate is correctly interpreted by browser, localhost should be added into domains managed by HSTS (chrome://net-internals/#hsts in Chromium) and all http:// tries should redirect to https:// version. Keep your redirects An important point is that HSTS only works after the user has received the header via HTTPS. So you will still need to have a redirect from your HTTP-site to HTTPS, also for supporting browsers that still do not understand HSTS. This is easily accomplished using Apache’s mod_rewrite:
<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteCond %{HTTPS} off
  RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
Thus, with a few lines of configuration, you can make the web a safer place to be for your users. HSTS is a supplementary method for basic security through standard redirections.

If you liked it, you should read:

📚 Newsletter Get new posts, recommended reading and other exclusive information every week. SPAM free - no 3rd party ads, only the information about waitingforcode!