The observant amongst you will have noticed that this website has become entirely secured by HTTPS.
If you didn't notice, then I've done my job correctly!
By redirecting every page to its HTTPS counterpart, every page you see here will be secured. However, I'd prefer all traffic was secured and reduce the number of redirections from non-secure to secure pages, and that's where HSTS (HTTP Strict Transport Security) comes into play. In this article, I'll explain my motivations, and how to implement HSTS on your own site.
So, why would I want to secure this site, since it doesn't accept payments?
Securing a webserver is more than just for accepting payments. Because a certificate issued from a major certificate authority will at the very least verify control over a domain (not necessarily ownership, though), a secured website helps with authenticity. This doesn't prove that I own the website (unless perhaps I had an EV certificate), but that the content you're seeing hasn't been modified in transit between my server and your browser.
A secured website also helps keep your details private; as what you browse and any comments you leave will be protected from sniffing. It also means that any cookies used by the server cannot be intercepted and tracked, as some ISPs are now tracking user habits by sniffing for cookies using transparent proxies.
Setting up HTTPS is pretty easy and well documented, so I won't go into detail here. In Apache, once you have your certificates generated and ready to go, you simply listen on port 443 instead of 80, turn on SSLEngine, set SSLCertificateFile, SSLCertificateChainFile and SSLCertificateKeyFile, and finally add SSLRequireSSL to your directory configurations just to be sure. If you're expecting large requests (i.e. users uploading files) then you'll also need to play with the value of SSLRenegBufferSize, but be very careful where and how you use this as making this larger can open you up to denial of service attacks.
Making sure everyone that visits your website sees only the secure version of the site is easy - you simply redirect every request for a non-secure page to a secure page. In Apache, I used the following virtual host to redirect every request to the same page but on the HTTPS version of the site:
Cookies are a particular problem, as they can allow you to be tracked, and even give out session information that can be used to hijack accounts (not a problem on this site, though). Cookies are sent to the server as a part of the request, so in the case of a user heading to a would-be secure site (i.e. https://simon.butcher.name/) using a non-secure address (i.e. http://simon.butcher.name), a cookie might be sent unencrypted. Despite the server redirecting the user to the secure version of the site, the cookie has already been sent in the clear and could have been stolen.
Strict Transport Security is designed to stop the browser from accessing the non-secure site entirely by rewriting addresses to use HTTPS automatically. The browser needs to be told when to do this as not all websites are secure. To do this, your non-secure (HTTP) site does nothing other than issue permanent redirects to new URLs, and your secure (HTTPS) site needs a new header: Strict-Transport-Security.
This header tells the browser to remember to rewrite all URLs as HTTPS URLs before making any requests, for the duration specified (in seconds). For example, if you want the browser to always use HTTPS for one month, you can add this in Apache:
Header set Strict-Transport-Security "max-age=2629743"
You may want to include all subdomains. For example, if your website is accessible as www.foo.org or just foo.org, you'll want to ensure the first visit to foo.org also protects www.foo.org. If you want to include all subdomains too, you can add the flag includeSubDomains, like so:
Header set Strict-Transport-Security "max-age=2629743; includeSubDomains"
There is no point including this header on the non-secure HTTP site because the browser doesn't know if HTTPS works, it cannot obtain the certificate's public key (more on that shortly), and the header can easily be inserted, modified, or more importantly removed by an attacker intercepting the unencrypted data. The header must be real — it cannot be added in by using an http-equiv meta tag in your HTML.
In theory, the first time you visit an HSTS “protected” site, you won't have any cookies set for the site and the browser will be told that from now on it should only connect using a secure HTTPS connection.
In practise, there are situations where a cookie comes from another domain (such as advertising and tracking cookies) and will be sent in the clear on the first connection, or where an unexpired session cookie is sent for a site where the HSTS rule expired in the browser. For “important” sites like PayPal, or even your bank's internet banking portal, this is a big issue as it's a hole in the security that can allow attackers to steal cookies if users still use the non-secure address. Stolen cookies can be forced upon the server in a form of replay attack in order to gain access or impersonate a user.
If you're using the latest version of Chrome, it's likely you've come to this website without even touching the non-secure redirects! You can have a peek at what's using HSTS through Chrome's internal debug page at chrome://net-internals/#hsts. Firefox also supports HSTS, but I'm not sure if it's using a preloaded list, nor where that data is coming from if they do support preloaded HSTS.
If you're a web developer and you're working with an HSTS-enabled site, make sure you ensure all of your cookies are set as secure-only cookies for a little extra protection.
So HSTS helps your website remain secured, but I haven't spoken about how it helps authenticity. Work has begun by Chris Evans and Chris Palmer (two more security gurus from Google) on certificate pinning. The idea is that the public key of your certificate is kept with the preloaded HSTS data so that the next time you visit the site you can verify that the site has the correct certificate. Google are implementing this for their own servers already, and this adds protection against a server with a certificate, probably generated after hacking into a certificate authority, and sending you to a fake server for phishing.
The ultimate goal of certificate pinning is to keep a hash of your public key (known as a “fingerprint”) in a well-known location, such as within DNS. When you visit the secure site, the fingerprint is recalculated and checked against the fingerprint the browser remembered to ensure the certificate hasn't potentially been replaced with a fake (i.e. redirected to a bogus server or a man-in-the-middle attack).
Additionally, using DNS to announce HSTS would mean preloaded lists can be eliminated, and the browser will know to always use HTTPS prior to making a request. Unfortunately DNS cannot yet be completely trusted until the widespread deployment of DNSSEC (security and authentication extensions to DNS). More news will come on this in the future, no doubt…
One down-side of all of this is that if you're in Iran or China then you probably cannot see site anymore, as very few secure websites are allowed through their government firewalls. Sorry guys, but that's not my fault!
If you think switching to HTTPS has put a strain on my server, you might be surprised to find out that it actually hasn't. CPU usage has increased by such a marginal amount that this argument against using HTTPS doesn't exist anymore, even with modest server specifications. If you think certificates are expensive, have a look for cheap domain validated certificates as they encrypt the traffic just as well as the hyper-expensive and highly validated certificates. There is a little more “chatter” at the start of a connection to the server than before, which impacts page loading times on high-latency connections, but broadband is quickly taking over and this is become moot too.
Aside from the obvious experimentation, the security settings on this site are intended to protect your privacy as best I can. I'm surprised the EFF haven't jumped on-board with HSTS yet.
As more websites turn to HTTPS, the attention of the attackers will also turn to HTTPS. HSTS helps overcome some of the simpler attacks, such as listening for cookies and requests being sent to the server unencrypted (by using a tool like Firesheep), but it also protects against SSL-stripping attacks (a form of man in the middle attack, such as used by sslstrip, or even some commercial firewall/traffic filtering devices). SSL-stripping attacks work by having an intermediary that negotiates the SSL connection on your behalf and sends you the unencrypted version of the page, having rewritten URLs in the document to use HTTP. This allows them to easily sniff your passwords and other details without worrying about decryption. With HSTS, the browser will automatically rewrite links back to HTTPS, but more importantly it would know that the site should have been secured and can act appropriately when receiving unsecure content.
I'd like to see more and more sites going HTTPS only, but sadly for most websites they are virtual-hosted on a single IP address. Extensions to SSL/TLS allow for virtual hosting, but in my experiments it's still very poorly supported, meaning for a good user experience only one HTTPS site can exist per IP address (and using different ports is impractical). For companies that virtual host all of their sub-domains on a single server, this can be worked-around by using a wildcard certificate, but ultimately IPv6 will probably help solve this problem.
HSTS is an Internet-Draft, not a standard (yet). The latest draft can be read here. The specification is likely to change slightly up until the point that this is published.
Two more articles related to HTTPS are in the works but haven't been published yet. Sorry for being so slow.