up

Zoompf's Web Performance Blog

Note: Archived Content

This is the archived version of the Zoompf blog. Since our acquisition by Rigor, all our new research and posts on web performance are being published on The Rigor Blog

SSL Performance Diary #2: HTTP Strict Transport Security

 Billy Hoffman on August 22, 2014. Category: Optimization

This post part of a series, where I discuss the steps I am taking to implement SSL on a website while simultaneously improving its performance. I previously discussed optimized SSL certificates. Today I’ll discuss a super easy SSL performance optimization that everyone should be doing: HTTP Strict Transport Security.

When we were designing the web interface to our new Zoompf Alerts beta website, SSL was a requirement from day 1. Not only did I want to protect our customers’s information, SSL provides a gateway to using SPDY, which can improve our site’s performance.

I wanted to make it as easy as possible for people to access the Zoompf Alerts beta website. Since I am using SSL, I wanted a user to be able to type app.zoompf.com into their browsers address bar and get properly redirected to https://app.zoompf.com. This meant configuring a website at port 80, whose sole purpose is to send HTTP redirects to the SSL version of the site on 443. But how does adding this HTTP to HTTPS redirect impact page load times? I ran a WebPageTest assessment to find out:

app.zoompf.com-waterfall

We see that the browser spends 179 ms, nearly 2 tenths of a second, connecting and wanting for the redirect to the SSL site. (We have to keep the time the DNS lookup took, since that would have to happen regardless of whether we were connection to HTTP or HTTPS). While 179 ms doesn’t sound like a lot, consider that the load time is only 1.391 seconds. This means our HTTP to HTTPS redirect accounts for 13% of our page load time!

Is there something we can do to eliminate this, while still making it easy for our users to reach our website? The answer is yes, by using HTTP Strict Transport Security.

Enter HSTS

HTTP Strict Transport Security (HSTS) is a web security policy mechanism that informs complying web browsers they are to interact with a specific website using only secure HTTPS connections. You can think of HSTS as kind of a caching header, but for the host/port/schema to access a website. You are basically telling the web browser “when you try to visit this domain within the next X amount of time, you must do so over SSL.” This means that the browser won’t make an HTTP request to “http://app.zoompf.com”, only to get redirected to “https://app.zoompf.com.” The browser will make a direct connection to https://app.zoompf.com. This has 2 performance benefits. First, you avoid needing a redirect from the HTTP to the HTTPS site. Second, you are ensuring that as much traffic as possible is using HTTPS, which means you can use SPDY.

Below is an abbreviated list of the HTTP headers that https://twitter.com returns.

Cache-Control: no-cache, no-store, must-revalidate, pre-check=0, post-check=0
Content-Encoding: gzip
Content-Length: 12264
Content-Type: text/html;charset=utf-8
Date: Fri, 22 Aug 2014 16:33:40 GMT
Expires: Tue, 31 Mar 1981 05:00:00 GMT
Last-Modified: Fri, 22 Aug 2014 16:33:40 GMT
Pragma: no-cache
Server: tfe_b
Strict-Transport-Security: max-age=631138519
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN

Twitter using the Strict-Transport-Security header to tell your browser that, for the next 90 days, always connection to https://twitter.com, and never to http://twitter.com.

Right about now you are probably asking yourself, “How does the browser know to communicate with a host using HTTPS without it first hitting the HTTP? Doesn’t the server still need to service an HTTP request originally to tell the browser to only use HTTPS in the future?” The answer is yes, but ideally only that one time. Consider trying to go to http://www.bank.com. You have never been there before. You get a redirect to https://www.bank.com. Once you access it over HTTPS, that is when you get the Strict-Transport-Security header that says “BTW, use the HTTPS for all communication in the future, and cache this directive for X seconds”. For all follow up visits, your browser won’t even let you go to http://www.bank.com. Even if you manually typed that into the browsers address bar, the browser automatically changes it to HTTPS because if the HSTS header. In many ways, you can think of this like HTTP caching, using the Expires or Cache-Control headers. However, with HSTS, instead of caching content, you are caching information about the communications channel to use.

There is an added security benefit to HSTS as well. The request to the HTTP site, and then the redirect to the HTTPS site, happens over an insecure channel where a user is not guaranteed to be communicated with my server. This creates a window of opportunity for an attacker with network access to redirect the user to a different site. The attacker could then trick the user into entering their credentials into an attacker-controlled website which is impersonating the Portal. Automated tools such as SSLStrip exist to do this. HSTS prevents this from occurring, by avoiding the HTTP request in the first place. In fact, its why HSTS was designed! The performance benefits are really just a side effect of the security feature!

While you can get some of this performance advantage by using a 301 redirect with a caching header, that approach is not as good as using HSTS. First of all, browsers don’t have to respect caching headers, and caching redirects behavior varies from browser to browser. Secondly, caches can be cleared, by the browser if it runs out of space, or by the user. HSTS is stored separately by the browser, and does not face these issues.

Currently 58% web browsers in use support HSTS. Implementing HSTS is as simple as included a special HTTP response header, Strict-Transport-Security, in each response from SSL site. This can easily be implemented via application logic, or with a web server level configuration rule. In fact, I implemented in ASP.NET with a single line of code in our master template: Response.Headers["Strict-Transport-Security"]= "max-age=1209600". The max-age number, much like in the Cache-Control header, is the number of seconds the web browser should remember to only access a site over SSL. Every time the user visits the site, the browser “resets” its internal value. I choice 2 weeks, since the usage of our app means a user will probably be looking at at least 1 page, once every 2 weeks.

If you are deploying a website that is SSL only, I highly suggest using HSTS to improve both performance and security. Since HSTS works at the hostname level, websites that have secured only part of their content with SSL can still benefit, assuming that separate content is served from a different hostname. This scenario is quite common with online shopping sites.

If you are interesting optimizing SSL for performance, then you obviously care about keeping your site fast and ensuring your visitors have a good user experience. Try out Zoompf’s Free Performance Report to get an idea of other areas you can improve, and to keep your site fast over time, check out our newly announced Free Alerts Beta!

Comments

Have some thoughts, a comment, or some feedback? Talk to us on Twitter @zoompf or use our contact us form.