Last week, Twitter temporarily stopped using OAuth authentication. The information they posted on their blog was pretty light on details, and the same thing goes for the security advisory that was posted later. Since then, more details and some better explanations of attack scenario’s have surfaced; let’s have a closer look at the security issue that was found and the potential ways this might be abused. If you have 15 minutes to spare, watch the latest episode of TheSocialWeb first:
Quick summary of OAuth
If OAuth is new to you, here’s a quick summary of what is does:
- Sometimes an application needs your account information to do cool things; such as posting things on Twitter for you, or reading your Gmail address book.
- Normally, that service would need your login and password to do this on your behalf. This is bad for a number of reasons; the most important ones for most users are:
- It requires the application to store your login name and password. If we’re talking about a web application, and that web application is hacked, the hacker might have your login info!
- If you change your password, you need to change it in lots of places
- OAuth changes this by creating so-called Access Tokens. If a website or program needs your account details to access another website, an Access Token is generated, and the user can then authorize that access token.
- Specific rights can be granted per access token; for example, reading your Gmail address book, but not deleting from it.
- If you want to revoke access, you can cancel the Access Token, which is a lot easier than changing your password and updating it in all places that still need it.
The figure below shows how this process works; for more details see the specification.
So what’s the security issue?
It might surprise you, but you can clearly see the security issue in the figure above. Of course, everything is a lot clearer in hindsight, so I’ll summarize the most important parts. For a longer explanation, Eran Hammer-Lahav has an excellent post with all the details you’d like.
Normally, an application that wants to use your credentials generates a request to authorize a token. You are then redirected to the site that the application wants to access (for example, twitter.com) and asked to log in. After logging in and authorizing the request, you are sent back to the requesting site, which does a callback to exchange the temporary key for the authorized key. Finally, using that authorized key, the application can gain access to the site it needs.
The problem is that there is no way to know whose key you are authorizing. So an attacker can sign up for an account on the application he wants to use, intercept the token that is generated, and get someone else to authorize it.
The attacker then uses social engineering to trick a victim into following that link (the authorization URI from the redirection). This can be as simple as a blog post with a review of the application, inviting people to try it out. When someone clicks on that link, they are sent to the provider to authorize access.
Since this is what he wanted to do, the victim will not realize that he should have started at the application itself, and will continue to sign into the provider. Because of how we train people to look for phishing attacks, even an educated user will notice that he is at the right place.
You’d have absolutely no way of knowing you authorized someone else’s key.
Can this be fixed?
There is a general consensus that this problem can be resolved. The most interesting solution I’ve seen so far involves using MashSSL as the underlying transport for exchanging OAuth tokens. Two proposals are currently being discussed; the latest state of the proposals can be found on the OAuth wiki. Both will require changes on both sides; the application requesting the tokens and the one granting them. The good news is that this only changes the process for requesting and approving them; so any authorizations currently granted will continue to work.