Oct 12 2013

"Trust me, it's secure"

There's a lot of sites—including some that want your credit card data, and even some operated by financial institutions—that are technically using HTTPS, but are still jeopardising users' security.

Some of them have a form to collect sensitive data which is served on a non-secure page, but submits to a secure page. Others collect sensitive data on a secure page, but that secure page is presented inside an iframe on a non-secure page. There are two huge security problems with this.

The first problem with this is that the user doesn't know it's secure. Sure, they can use their browser's web developer tools to inspect the form or iframe element, but most users won't know how to do that, and the users that do know will probably trust you less for the fact that they have to.

Many of these sites feature prominent messages saying "THIS SITE IS SECURE" and containing clip-art pictures of padlocks; these are meaningless, and web-savvy users know that. (In fact, those web-savvy users will, once again, probably trust you less for it.) These sites are telling their users "trust me, it's secure", without actually proving it.

The second problem is the big one: the insecure page itself is a weak link. In an ideal situation, all of the data is sent over a secure connection; our system is secure against passive interception. Let's say our user, Alice, is trying to buy something from Bob's Online Store using her favourite cafe's open WiFi. Eve is sitting the next table over, sniffing wi-fi traffic. Our system foils her for now.

But, if we were always dealing with ideal situations, we wouldn't need HTTPS in the first place. Later, at another cafe, Alice decides to make another purchase. She connects to the cafe's wifi, and once again fills in her credit card details. This time, Mallory is sitting across the room with an espresso, a copy of the Sunday Mail, and a fake access point running all traffic through something like sslstrip, which modifies the insecure page in-flight, so that the links pointing to the secure page now point elsewhere. Alice doesn't realise that the form has been tampered with, and will now submit to an insecure URL, until she starts seeing strange charges on her credit card days later.

One page isn't enough

The easy way to protect users from this sort of thing is to properly secure the data entry page, and tell them to look for the padlock (or, in the case of a site with Extended Validation, the "Green Bar"). But there's still a problem: the other pages that the user clicks through to get there. If they're not secured, our attacker can still launch her HTTPS stripping attack earlier in the process. Users are rarely diligent enough to check the address bar every time, particularly with the complacency that comes with a familiar site. (While the Big Four Australian banks all have encrypted internet banking login pages, all but Commonwealth fall down at this point.)

The only real solution, then, is to secure every page on the website, from the homepage the user sees when they type the address in onwards. But we're still not safe yet! Users generally type URLs in without a scheme (e.g. typing in commbank.com.au, instead of https://commbank.com.au), and browsers will interpret that as a HTTP URL. Commonwealth's servers, like almost every other HTTPS-only site, will respond by redirecting the browser to HTTPS, but since the redirection itself happens over HTTP, it can still be intercepted.

Sadly, there's no foolproof way to ensure that all requests to your site are sent through HTTPS from the get-go, but we can come close with HTTP Strict Transport Security. Sites that use HSTS send a response header that tells the browser "this domain operates over HTTPS only", and from that point onwards browsers automatically rewrite all requested URLs for that domain to HTTPS before the request is sent, regardless of whether they came from a user's typing, a link, or an embedded resource in another page.

Despite how easy implementing HSTS is—for nginx, just add the single line below to your server block—not even Commonwealth are using it.

add_header Strict-Transport-Security max-age=31536000;

Edited on 9 July 2017:

Since this article was written, all of the Big Four banks now serve their entire sites over HTTPS. Commonwealth and Westpac now also send Strict-Transport-Security headers; NAB and ANZ are still vulnerable to the attack described above. In addition, Web browsers now ship with a "HSTS preload" list built in, which thwarts this attack even on the first time a user visits a site; of the Big Four, only Commonwealth is on that list.