I had an interesting question pop up on my “SSL is not about encryption” blog post this weekend:
I have a question about logging to site like StackOverflow which doesn't use SSL at all.
If I am login to SO via Google. Is this secure in this case?
This is actually a very good question for a number of reasons so I thought it deserved a little more attention than just the short response I gave on the blog. The question implies there is some sort of absolute state to security (probably unintentionally) where a site such as Stack Overflow is deemed to be either “secure” or “insecure” (hence the quotes in the title).
The reality is that there are a few more twists to it than that and Stack Overflow in particular is an interesting case study due to their use of a third party authentication provider. What this blog post will show you is that in this particular case, we’re really looking at two different security domains with different levels of protection and in the case of Stack Overflow, yes, it’s kind of secure – but then it’s also kind of insecure too…
Stack Overflow and the role of OpenID
I’ve followed the evolution of Stack Overflow from the very early days and one thing that Jeff Atwood was always adamant about was the role of OpenID. Jeff has many, many good points and probably the most significant one from a security perspective is that it makes the job of keeping credentials safe the responsibility of someone else. This is a good thing, particularly when you consider the work organisations like Google they’ve done around two factor authentication. Now of course there are other OpenID providers who are not quite as well equipped, but certainly they still do a very good job of implementing secure authentication mechanisms.
There are opponents of OpenID, but the arguments are more about the logistics of implementing it and dealing with customers having accounts with all sorts of different providers. These are perfectly valid concerns, but they’re not about security; all the OpenID implementations I’ve seen adhere to all the sorts of good account management practices I regularly talk about such as no restrictions on password length or structure, well implemented password reset processes and of course everything is done over HTTPS.
But what we need to remember is that OpenID is being used by Stack Overflow solely for the purpose of authenticating the users. What happens after this is a whole new ballgame.
Stack Overflow and HTTPS
Here’s what you currently see on Stack Overflow today:
This is really what Marek was referring to in the initial question which sparked this blog post and as he has rightly observed, there is no use of HTTPS. But is this a problem? I mean I’ve already logged on via OpenID so my credentials have been sent securely already, what’s the risk?
To answer that question, let’s start by taking a look at the cookies set by the site. Why? Because cookies are how our logged in state is persisted across multiple requests over HTTP which is a stateless protocol, that is each request is made over a new connection totally independent to the other requests. In other words, HTTP itself doesn’t know we’re logged in, it needs help from cookies.
So about those cookies:
What you’re seeing here is Edit This Cookie (a Chrome plugin) and as with most websites, there’s a collection of various cookies (also as with most websites, the last four are set by Google Analytics). The one we’re interested in today though is the “usr” cookie which looks like this:
I’ve blanked out some values in the cookie for reasons which will become apparent soon, the main thing to remember is that this cookie is going to be sent with every single request to the Stack Overflow website. It will also be sent in plain text as we’ve requested the page over HTTP, not HTTPS. As a consequence, the “secure” attribute is also not set as this would prohibit the cookie from being sent over an HTTP request.
The impact of cookie theft
The “usr” cookie is what Stack Overflow uses to identify which logged on user is making the request. What this means is that if an attacker can get their hands on the cookie, they can recreate the session. Let me demonstrate – here’s a new browser instance using Chrome’s incognito mode which ensures no existing cookies are passed in the request:
We can clearly see the “log in” link meaning we are not currently in an authenticated session. Let’s change that:
What you’re seeing here is a little feature of Edit This Cookie which makes it simple to add your own. This isn’t rocket science – there are plenty of ways of doing this – this just makes it very easy. Let’s submit the cookie then send it to Stack Overflow by simply reloading the page:
Hey, look at that! We’re still in the incognito browser session (note the spy in the top left corner) but now you can clearly see I’m logged in as myself again. Except I didn’t log in, I just stole my own cookie. Nobody cares if you can steal your own cookie, but they’d care a great deal if somebody else can steal your cookie. Let’s look at how that can happen.
Session hijacking of non-HTTPS requests
So this is what brings us back around to HTTPS or in Stack Overflow’s case, the lack of it. If that cookie is sent over plain old HTTP, it’s vulnerable to what we call “session hijacking” which is essentially what I did above, expect it’s normally done by someone with malicious intent hijacking someone else’s session.
Back in OWASP Top 10 for .NET developers part 9: Insufficient Transport Layer Protection I picked up a $27 Alfa AWUSO36H from eBay:
This is a Wi-Fi adapter that supports promiscuous mode which simply means it’s able to receive wireless packets which may not necessarily be destined for its address. In the OWASP post mentioned above I explained how I headed down to the local McDonald’s, started browsing a non-HTTPS enabled website on my iPad then used my laptop with the AWUSO36H running a BackTrack Linux virtual machine which allowed me to intercept enough traffic to grab the cookies and hijack the session. It really is that simple.
This is probably not the first time you’ve heard of this kind of attack. Firesheep gained notoriety a couple of years back because it allowed anyone to do the same thing simply by installing a Firefox plugin. What made Firesheep so dangerous was that it specifically looked for cookies from sites such as Facebook, Twitter and Flickr. This meant that anyone could go and sit themselves down at an internet cafe, open up their browser and see this:
(from How to protect yourself from Firesheep)
Choose a user from the panel on the left and bingo – you’re logged in as them. It really is that simple and the same thing could be done with Stack Overflow. Actually, Firesheep was arguably the catalyst for some of the sites it targeted implementing HTTPS far more broadly.
The risk to users of Stack Overflow
So what can an attacker do if they hijack your Stack Overflow session? Well the obvious thing is that they can post anything under your identity; questions, answers and comments, for example. Of course the other thing they can do is change any profile attributes:
For the most part (with the exception of birthday), this is publicly visible but it’s info you don’t want other people changing. This one is a little more damaging though:
If an attacker can add additional login accounts then they can create a persistent mechanism to get back into that Stack Overflow account at any time without needing to hijack the session. Now of course the victim can always go into their account settings and identify the presence of the new login, but it’s a question of how much damage is done before then.
How would an attacker mitigate the risk of having their newly added account removed? Just remove the victim’s original account(s) instead:
This would not be a very pleasant experience to be on the end of and would inevitably lead to the victim needing to attempt to re-establish their valid ownership of the account with the guys running Stack Overflow.
Of course the other thing an attacker could do is log in to any other Stack Exchange account the victim uses:
This is a great usability feature but it does mean that any Stack Exchange site you’ve previously logged into becomes vulnerable if any other session on another site can be hijacked. Alternatively, if you can add another authentication provider then the attacker can login to any Stack Exchange website whether the victim has used it before or not. I can image some potential for reputational damage if an attacker was able to start expressing opinions on sites like Christianity or Judaism.
How realistic is this? And what should be done?
Firesheep has showed us that this sort of scenario is entirely feasible and certainly the risk it exploited is common on any website which persists the session via cookies sent over HTTP. Here’s a scenario for you: consider a developer conference offering free Wi-Fi – how many times would plain text authentication cookies be passed over the network and be potentially observable by anyone? Remember, it only takes one request and that could simply be opening the browser which loads tabs from the previous session, one of which may be Stack Overflow.
One mitigation would be to do what many did in the wake of Firesheep and use a plugin which forces requests to certain sites to go over HTTPS such as the Use HTTPS extension for Chrome. But unfortunately, that isn’t an option in this case:
Stack Overflow doesn’t offer HTTPS at all, as you can see for yourself by trying to access the site over a secure scheme: https://stackoverflow.com
Of course another option is to simply stay off public Wi-Fi when using Stack Overflow. If you really want to go and answer some questions over a latte, use a personal wireless hotspot which isn’t shared publicly. But this doesn’t completely solve the problem because every node those packets move through can potentially intercept, read or even change the contents of either the request or the response. It’s entirely feasible for this to happen at the ISP level, just look at Tunisia.
The only real means of ensuring sessions can’t be hijacked in this fashion is to implement HTTPS on every authenticated request. If in doubt of the necessity of HTTPS, let’s refer back to the OWASP Top 10 which is somewhat of the bible for securing web apps. In particular, here’s what’s in the Transport Layer Protection Cheat Sheet (emphasis mine):
The login page and all subsequent authenticated pages must be exclusively accessed over TLS. The initial login page, referred to as the "login landing page", must be served over TLS. Failure to utilize TLS for the login landing page allows an attacker to modify the login form action, causing the user's credentials to be posted to an arbitrary location. Failure to utilize TLS for authenticated pages after the login enables an attacker to view the unencrypted session ID and compromise the user's authenticated session.
This may seem like a burdensome process and indeed there would be some performance impact, but then again, here’s what Google had to say after making GMail HTTPS only:
In order to do this we had to deploy no additional machines and no special hardware. On our production front-end machines, SSL/TLS accounts for less than 1% of the CPU load, less than 10KB of memory per connection and less than 2% of network overhead. Many people believe that SSL takes a lot of CPU time and we hope the above numbers (public for the first time) will help to dispel that.
I don’t want to trivialise the effort as the impact goes beyond just infrastructure, but certainly it’s not the performance and cost game-changer that some people would like you to believe.
Summary
The guys at Stack Overflow know all this already. They know exactly what the risk is and how it could be exploited and they’ve made the decision not to implement HTTPS with full cognisance of the risks. Indeed Jeff even wrote about whether all web traffic should be encrypted earlier in the year (and yes, I’m aware he has since moved onto other things) and specifically pointed out that “I can't really construct a credible argument against doing this [using HTTPS]”. I haven’t spoken to anyone at Stack Overflow, but we’re talking about a bunch of the smartest developers you’ll meet, of that I have no doubt. Jeff does go on to make some very valid points in his post about some of the barriers a site such as Stack Overflow would need to overcome to properly implement HTTPS and I’m also going to agree with him that we shouldn’t be out there berating every public website which doesn’t offer encrypted connections. Still, it’s a risk to be conscious of and healthy discussion around it is always a good thing IMHO.
So going back to the original question, is Stack Overflow “secure”? This question implies an answer which is absolute and that is rarely ever the case in security. Credentials are well secured and indeed this isn’t even Stack Overflow’s responsibility. I also wouldn’t be too concerned about sitting at home and using the site on a well secured network. Yes, there is still a risk present that wouldn’t be there if the traffic went over HTTPS but then again, I don’t think the Aussie government is that interested in my Stack Overflow account (although different countries and different Stack Exchange sites may be a different story).
The only instance in which I’d really urge caution is that public Wi-Fi scenario, particularly when you’re in an environment surrounded by other people with technical know-how. Mind you that guidance goes well beyond Stack Overflow too and I suggest using the Wireless Hotspot on your iPhone (or equivalent) in these circumstances. Consider it a little bit of insurance.
Finally, this is also a lesson for those considering using third party authentication providers. Yes, it’s great that you can farm off this work to someone who has a solid implementation, but you still have responsibility for securing the authenticated session on your site. If you choose not to, be aware of the risks because certainly we’ve seen them exploited before.