Web security headers you should be thinking about - HSTS

Your website really isn't 'secure', though you probably know this. As a developer or product owner, you know the real idea behind web security is to only make it hard enough for an exploitation artist to give up and try another target less secure. It's kinda like running from a bear; you generally only have to outrun your friends. However, if you slap the bear in the face, then it doesn't matter who you out run, she is going eat you... then probably your slow friends.

But web security is hard, right? Well, yeah it can be, but there are many simple things you can do (simple like 3 lines of code simple) to give added protection to you and your users; some things you might not have thought about. Over the next few posts, I'm going to point out the security headers you should be thinking about. I'll address what they do, how to implement them, and any vulnerabilities they may still expose.

HTTP Strict Transport Security

What does it do?

It tells the browser that the site (and its content) can only be accessed over https.

"But my website already uses SSL!"

Yeah, well do you still serve content over unsecured http? Then your site is more vulnerable to a man-in-the-middle (MITM) attack.

"Actually, we already redirect all requests from http to https so our users are secure."

Your users are indeed more secure once they have switched over to https.  But picture this scenario: your user is on a compromised network and all of their traffic is being routed through an attacker's laptop. Your user then goes to www.yoursite.com. At this point, the attacker can serve their own version of your site and embed malicious scripts to steal private data the user enters (like credit card information) or whatever else they want all without the browser being aware.

This will actually always be a problem with redirecting http to https. If an attacker was present for the first connection of an http session, https is useless because the attacker will not redirect the user to the secured site. Now, if the user actually enters https, then a MITM attack becomes quite a bit harder, but not impossible... but that's another post.

Back to the header. When you perform a canonical redirect from your http site to your https site and you add the HSTS header to the https response then your browser knows to always use https for the current connection. But here's the magic sauce... your user's browser caches the response so when the user closes their browser and goes back to your http site later on (before the cache expiration), the browser remembers the HSTS header and automagically appends the little 's' to the http without relying on the redirect!

Now this doesn't fix everything. Assuming https isn't compromised, there are three scenarios in which a user could still be successfully attacked via MITM.

  1. The very first time your user accesses your site before your server has had a chance to redirect to https which includes the HSTS header.
  2. The HSTS header has expired and the user attempts to go to http.
  3. The user clears the browser cache and goes to http.
Remember, once the server has sent the header, the browser will remember it for future requests (even after the browser has been restarted assuming the cache hasn't been cleared or expired).

How do I do it?

So let's take a look at this header:
Strict-Transport-Security: max-age=15768000 ; includeSubDomains
'max-age' tells the browser how long to cache the header.

'includeSubDomains' tells the browser to enforce the header on all subdomains (example.com and foo.example.com).

To enable this header in your MVC 4 App, you only need to write a few lines of code:

public class HTSTHeaderOption: System.Web.Mvc.ActionFilterAttribute
    public override void OnResultExecuting(System.Web.Mvc.ResultExecutingContext filterContext)
        filterContext.HttpContext.Response.AddHeader("Strict-Transport-Security", "max-age= 604800; includeSubDomains");

Now for the part you've been waiting for... which browsers support this?

According to OWASP (as of 01/01/2013) here are the supporters (source):

Browser Support Introduced
Internet Explorer no support as of IE 10 (tested on 2013-01-01)
Firefox 4
Opera 12
Safari  ??
Let me know if you have any questions or if you want to add or modify anything I've said here.