Second Line of Defense in Web Applications Part 4 HTTPS and HSTS

The last posts focused on defenses against Cross Site Scripting. Today we will start with defensive
mechanisms that help to prevent errors with transport security.

TLS Enforcement with HTTP Strict Transport Security (HSTS)

Another problem with web applications is that they usually start in an insecure state. What this means is that the initial page is usually accessed via HTTP. The application then enables transport security with SSL/TLS by switching to HTTPS. This will protect all transmitted data. But the problem is that the change to the secure connection is signalled over an insecure connection. A typical man-in-the-middle attacker is usually able to modify the network traffic. He can easily replace all “https://” links on the page with “http://” and trick the user into accessing the web application in an insecure way. If the attacker goes further and acts like a proxy and talks to the client with normal HTTP and to the server in secured HTTPS he can intercept the traffic, without the user seeing any certificate related warning or the web application detecting access to critical URLs over HTTP. This attack is called “SSL Stripping“.

It is already hard enough to educate users not to ignore certificate warnings, but to get them to be suspicious about the absence of a green lock icon in the address bar is even harder. There are several browser add-ons such as HTTPS everywhere, which try to detect HTTPS support on the first access and force it on later access. But not everyone uses such add-ons and browsers are unlikely to include such functionality, as it’s still perfectly reasonable to serve a site over HTTP and also HTTPS. As solution to this it was proposed that a web applications can instruct the browser that they want HTTPS to be enforced.

To instruct the browser to use HTTPS for the site the web application can send the HTTP Strict Transport Security (HSTS) HTTP header. The header must contain a “max-age=” directive, which indicates that the HTTPS enforcement is valid for that period of time. After that the browser must check again if the HSTS header is still sent. It is also possible to force HTTPS for all subdomains with the “includeSubDomains” directive. The following example will instruct a browser to force HTTPS for the domain and all subdomains for a year (note that max-age is in seconds).

Strict-Transport-Security: max-age=31536000; includeSubDomains

HTTP Strict Transport Security is supported by Chrome 4+, Firefox 4+ and Opera 12+. So if a browser has saved the Strict Transport Security setting for a website he will connect to this website only using HTTPS. A man-in-the-middle attacker has no chance of performing SSL stripping because the browser will simply refuse to connect via HTTP and automatically switch to HTTPS for every request. To protect further against man-in-the-middle attacks HSTS requires that there are no TLS related warnings (such as an invalid certificate). HSTS also helps to protect against some simple user errors. For example if the user explicitly types http:// into the URL or uses a bookmark that is set to http://.

All in all the good browser support, the simple deployment and no downsides for the web application show that this is an easy and effective mitigation. More information can be found here and here.