4 Things to remember about OAuth2

Andriy
Pashkevych

Lead Software Engineer
@EPAM
Speaker JavaDay 2014-2015

4 Things to remember about OAuth2


In this scenario, OAuth2 is oftentimes the way to go – industry standard with high-quality open-source implementations available on the market.
However, while OAuth2 seems simple it has its own pitfalls, which can lead to security vulnerabilities. This article outlines 4 points, which you need to remember, in order to avoid introducing sneaky security bugs.

Disclaimer

This is article is not meant to be a guide on how to use OAuth2. In fact, there are several tutorials available on the net as well as the spec itself (RFC 6749).
I also assume you already do understand the four flows of OAuth2 protocol. If not – there are plenty of sources online, to look up the info.

A few interesting facts about OAuth2

Before we dive in into the OAuth2, let’s review the problem we are trying to solve – Authorization.
There’s nothing new – you need to make sure a certain resource is only available for the entities that have the rights to use it (be it humans or applications).
People have been solving this problem long before OAuth appeared. Proprietary protocols where developed by many popular API providers, such as Google, Yahoo and others. Some of these implementation have managed to stick around for a while, such as Google ClientLogin, which was shutdown only in April 2015.
Then, OAuth protocol was an effort to develop a standard, which would solve the problem once and for all. OAuth1.0 (RFC 5849) was released in 2010 but failed to become the industry standard, because it was too difficult to use.

OAuth2 protocol (or maybe not a protocol)

WIth OAuth1 failing to solve the problem expert group was created to work on OAuth2 protocol, which was aimed to solve the problems of OAuth1.0.
Yet, things did not go as planned and 3 years after starting the OAuth2 development specification was not finalized and several trade-offs had to be made, in order to simplify the protocol.
As a result, OAuth2 specification became so loose, it was no longer considered a protocol by the authors themselves, instead they call it a framework!
Also, the specification clearly says that it is unlikely to produce inter-operable implementations. Which means you are not likely to have part of your OAuth2 infrastructure running on Spring Framework and other part on Apache Oltu, because they won’t be compatible!
Eran Hammer, protocol development lead, sums it all up in this talk.
After reading the above – you may ask a natural question, why use OAuth2 then? The answer has two parts:
1. It is an industry standard
2. You are unlikely to produce a better standard
With a grain of salt and realization we still have to use it, lets switch to the protocol itself.
Here’s a quick reminder of what OAuth2 is. The protocol is build around the idea of tokens. A token is an entity which represent a set of permissions. So, if you want to make an authorized request to a service – you need to present it with a token, instead of a login and password.
Now, obvious question is, how to obtain such a token. Large part of the OAuth2 spec describes the procedure. In fact, there are 4 ways:
1. Authorization Code Grant – when client is a server application
2. Implicit Grant – for temporary access to the data, typically used for javascript clients
3. Resource Owner Password Credentials Grant – for mobile apps
4. Client Credentials Grant – for applications acting on their own
Once you are confident about your understanding of the above flows, check the points to remember. Hopefully, they will save your application from a security vulnerability.

Point to remember #1

Keep clienid and client secret separate from refresh tokens!

This only applies to Authorization Code Grant.
When using authorization grant flow, you will typically store refresh tokens in a database. Also, when you start with just a few clients, you might want to keep their ids and secrets in a property file. But when the number of clients grows and you need an efficient way of managing them you may also want to store clientids and secrets into a database, which happens to be the same where you store your refresh tokens. Stop here!
If the database gets compromised the attacker will be able to pretend he is a legitimate client, forever.
Consider the alternative, if you would store the client ids and secrets separately and the database with refresh tokens was stolen – the attacker would only be able to use the tokens until they expired.

Point to remember #2

Expire the tokens frequently!

Remember, in some scenarios token can be stolen and token expiration is one of the ways to increase security. You may ask, how long a token should live? The answer is – expire it as soon as you can. This is similar to variable visibility – you should always stick to the minimum which suits your needs.
It may be tempting to make tokens which are valid for weeks. Think carefully, when making such decisions.

Point to remember #3

Remove the token from the url first!

This only applies to Implicit Grant flow.
Make sure that the first script you load is the one that will remove the token from the URL! Implicit Grant is the flow which requires the token to be shared with the browser, via URL. As long as the first script on the page removes that part of the URL – you are safe. However, it is very easy to forget about it, in the long run.
Imagine, after you’ve implemented Implicit Grant flow, you also have to add Google Analytics to your pages and you end up placing Google Analytics script before your OAuth2 script (the one which removes the token). If this happens – all the tokens will be sent to Google Analytics, as a part of the URL. Not something you want.

Point to remember #4

Educate your users!

This case concerns native mobile applications, using Resource owner grant flow.
Client credentials flow means that users will share their credentials with the client (native mobile app). And it is only intended to be used with strongly trusted clients. Or the apps you build yourself.
However, there is one problem here, if your users will get used to the fact that they can input their user name and password into a native app, chances are high that someone else will build a native app, which will look similar to yours and will collect your user credentials, simply because they have a habit to type those into native apps.
So, make sure your users are aware of the fact they should not input their creds into any applications, other than the one you’ve built.
Conclusions
Remember, even if you use out of the box OAuth2 implementation, you should still think carefully about what you build.
I hope the above points will make you review your application and eliminate a bug or two.