For years, security folks — myself included — have warned about the risk of personalized web sites such as Google, Facebook, Twitter, etc. being served over plain HTTP, as opposed to the more secure HTTPS, especially given the proliferation of open wifi networks. But warnings from security freaks rarely get people’s attention. A demonstration is worth a lot more, and that’s exactly what Eric Butler did with FireSheep, a Firefox plugin that lets you instantly see who on your local network is surfing well-known sites, grab their unencrypted cookie, and “become” them on the given site. Nice work Eric!
(I must also point out Ben Laurie’s post on this topic and his always-hilarious take, “these are not the credentials you’re looking for!”)
Some folks are wondering if this will be a watershed event where major sites will suddenly shift to serving everything over SSL. I don’t think so. The performance implications of serving everything, including static content, over SSL, are staggering. While working on my secure voting system Helios, I noticed that I could easily serve a static image over HTTP about 1500 times per second on a medium-sized server. Add SSL to that, and squeezing out more than 50 images per second becomes a significant challenge. Now, I’m sure there are folks who can tweak SSL far better than I, but it’s still going to be a significant amount of overhead, not to mention that caching content over SSL typically doesn’t happen, which means every graphic, every JavaScript file, is reloaded every time the user navigates to a new page. At the end of the day, a web site served over SSL is a significant amount of extra server-side overhead and, even if you do it right, it just won’t be as snappy in the browser. Users will complain, and that makes SSL-everywhere very unlikely. I would be happy to be proven wrong, but I just don’t think SSL everywhere is happening anytime soon.
What sucks is that there is no in-between. It would be nice if a web page could mix and match SSL and non-SSL components, so that images and JavaScript could be loaded without the overhead of SSL. Of course, that’s not nearly as secure, but it would defend against a passive attacker like FireSheep. Active attackers would still be able to cause damage, but then again active attackers are quite a bit harder to achieve and to defend against, so maybe an in-between defense is good enough. Unfortunately, if you try to mix and match secure and insecure resources, you get some nasty warnings / broken locks on most browsers. For good reason, too, since the browsers are defending against active attackers, but still, too bad there’s no usable way to achieve in-between security.
It would also be nice if web developers could easily use a more secure approach to authentication, one that doesn’t simply send over a cookie. Something like HTTP Digest Auth, only of course *not* Digest Auth itself since that doesn’t fit in nicely with the way web sites like to manage their users’ sessions (timeouts, explicit logout, …)
SessionLock Lite
A couple of years ago, I proposed an in-between solution called SessionLock [PDF]. This approach uses a combination of JavaScript and message-passing via the URL fragment identifier to cause every link, every AJAX request, etc. to be signed. Think of this as a more powerful version of HTTP Digest Auth that allows web sites to fully control login/logout procedures. The content of the web sites you visit with SessionLock is not protected. If you look at what your friends are doing on Facebook, someone with FireSheep might be able to see that, too. But, crucially, they wouldn’t be able to post new status updates, add friends, view data you haven’t viewed yourself during that session, etc. Is that good enough? I’m not sure, but I do think it provides a much more intuitive level of protection: when you’re on a public wifi network, you should always assume someone is casually looking over your shoulder. But you shouldn’t have to worry that they’re completely taking over your keyboard (I mean, that’s just rude!)
Shockingly enough, SessionLock has not caught on, and I often cry myself to sleep at night wondering why… Maybe it was too complicated? So, for those web sites thinking about what to do to respond to FireSheep, I propose SessionLock Lite. It requires a modern browser, IE8+, FF3+, Safari 4+, or Chrome, and it doesn’t fully protect against FireSheep, but it makes FireSheep’s stolen sessions valid only for a very short period of time (a few seconds). Could this be a reasonable compromise?
The idea is this:
- the web site, say facebook.com, logs you in over SSL the way it currently does, and sets a secure session cookie that is only transmitted over SSL.
- when the site redirects you to the plain HTTP site, the way it currently does, the plain HTTP site opens up an invisible IFRAME onto the SSL-protected version of the site.
- the SSL IFRAME computes, every few seconds, a new token that is timestamped so it is valid for only a few seconds. This is likely done using HMAC and the secure cookie as the key. HMAC can be computed in JavaScript in a few milliseconds.
- the new token is communicated to the containing HTTP frame using postMessage(), which is the main reason you need a modern browser.
- the containing HTTP frame then uses this token as its unencrypted cookie.
Effectively, the SSL channel is used to refresh the session cookie very rapidly, all locally in the browser, without making SSL requests to the server other than the initial request to a very small file when the page loads. This is particularly optimized for AJAX-heavy sites like Facebook and Twitter, where the SSL IFRAME will live on for minutes or hours. While you’re using the site, someone on FireSheep can use it, too. But the moment you stop using it, they can no longer use it either.
This is not anywhere near a complete solution, but it’s a very cheap solution that costs almost nothing performance-wise, requires changing very little code, and certainly reduces the damage FireSheep-wielding attackers can cause.
Pingback: Benlog » OK, let’s work to make SSL easier for everyone