Thursday, 21 January 2016

Facebook and Google (and other) OAuth2 Logins are NOT always authentication

As people are trying to understand more about web security, we have confused two concepts that are related but not the same: authentication and logging in. You might naturally think that authentication is required to login (at least in systems that have some kind of "login" system) but that is not true and it has come out of the OAuth2 myth.

The OAuth2 myth is that OAuth2 is Open Authentication 2. It is not. It is Open Authorisation 2. If you do not understand the difference, let me define it: Authentication is making a (semi-provable) claim about who you are to the system. Authorisation is asking what an entity is allowed to do or delegating permissions on behalf of someone else. Note that you do not need to be authenticated to use authorisation since an anonymous user will still have some types of permissions on a site.

Firstly, why is authentication only semi-provable. Well, as a person (more generally, an entity), you are supposedly proving who you are by one of the 3 factors of authentication e.g. a password but that does not prove to any high level of assurance who you are, since a password is transferable. In fact, in most systems, even 2nd and 3rd factor logins are not always proof at any absolute level since even if the hardware is reliable, it is sometimes possible to break a system elsewhere. We accept that risk to provide something usable. It would be impractical to require some kind of ultimate proof of identity to access our GMail although, of course, people are working on ways to make this proof of identity process more secure.

So let's start from the basis that we will trust that knowledge of a password is an acceptable level of proof for authentication. If we write our own authentication code, we are likely to have a username (or email address) and a password. When done this way, we specifically tie authentication to logging in but as Dominick Baier stated, "we don't do our own auth any more do we? This is the 21st century". There are many reasons why delegating our authentication to another provider is desirable from the convenience of not needing people to sign up to our service, through to the fact that a single-sign-on provider is more likely to be implemented securely than doing it ourselves (I am not aware of any SSO providers who have been hacked).

So we can just use SSO right? Facebook, Google and several others provide OAuth2-based login capability, it is pretty easy to integrate and it works. However, we have unknowingly believed the myth that OAuth2 is providing us with authentication. In most cases it isn't!

A few years back, there were three, seemingly competing systems, for our use in centralised authentication. SAML-based systems were designed for the corporate world and are heavyweight, XML-based (with all the pain that involves) and are largely completely impractical for the public web. Even corporates struggle with SAML! The second, openid, was designed for the web but was also very complicated, both to understand and to implement - perhaps because it was trying to do too many different things at once. Sure, some of these might have been optional but perception is everything, and people decided they didn't like it. Along came Twitter who were trying to create their openid implementation and realised that there was no system to delegate API access, something that was important at the time as APIs were becoming all the rage. They created OAuth v1 with a group of other people and produced something that was much simpler than openid. Somehow, people got confused at the distinction and started to see and use OAuth (and its simpler and more popular version 2) as an authentication mechanism.

For some reason, this myth has never been adequately dispelled and Facebook, Google and other providers are very commonly used for authenticating into web sites - many times, not using the optional mechanism that adds authentication to the protocol (see later).

You could argue that authentication is a specific subset of authorisation i.e. User X has permission to log in and although that is true, it is the breadth of the spec that provides various other ways in which a system can still "authenticate" using OAuth2 without the user being present and therefore without true authentication taking place!

Let us consider a simple way in which we can see that Facebook login is not authentication. We assume that if someone enters their password in a normal situation, that they are present and have proved to an acceptable level that they are who they claim to be - they have authenticated. What happens when you login to the same site with Facebook? You might have noticed that if you are already logged into Facebook in the browser (which we all are right?) and that the Facebook session seems to last forever, we are NEVER asked for a Facebook password. We simply give permission for the calling application to access our details and we return to the site and are logged in! In other words, for most of us, all an attacker needs is access to our computer and they can "authenticate" into thousands of web sites without ever needing to know our password - it's not authentication at all!

Why is it this way? OAuth2 is not designed for authentication but for API access. If a site is accessing our FB timeline or our Twitter feed, it would be unusable to ask the user to enter their password every time access is made. In fact, the access is allowed to be made when the user is not even present in most cases and can be made over several days or weeks. The user has the ability to revoke this permission but it still holds that the concept of the user being present is never required in the protocol - it is up to the provider to decide how they want to give the user the choice to allow or disallow access.

So can OAuth2 never be used for authentication?

There are two ways that it can. The first of these is to do what we have done at PixelPin. We have limited the parts of the protocol that have been implemented (for instance, there is no long term or unattended access to our system) and we also require the user to authenticate every time PixelPin is invoked. This way, we remove the vectors that would allow the data to be retrieved automatically at a later date. It is also for this reason that we do not need to revoke permissions for applications since they are only given access exactly once per session after authentication.

The second way, which is necessary for sites that do have APIs and do need to allow long-term access is to use OpenID connect. The OpenID group have presumably noticed that OAuth2 was being used incorrectly and insecurely and have produced a mechanism designed to sit above OAuth2 so that it can be easily introduced into existing providers and which is both more specific on fields that are used in the handshake (OAuth2 is deliberately vague and encourages non-standard implementations!) and also provides a signed authentication token as part of the handshake which provides a provable way to tell the calling site what authentication was used for this user during the handshake. The mechanism allows either the calling site to require authentication during the OAuth2 handshake or at least allows them to know what has or hasn't taken place so that certain future actions might trigger a full authentication.

At PixelPin, we are looking to implement OpenID connect over the next few months, despite not needing to on our system, to ensure that we are using the latest security best-practices and to give people the option to plug pixelpin into a standard OpenID connect plugin (whereas currently, most plugins require specific code for each authentication provider).

Watch this space!


Post a Comment