32

I have a basic doubt or apparently am missing out on something fundamental. When talking about an Android app that talks to the backend using APIs, the access to the resources/APIs are protected using access tokens and refresh tokens (much like OAuth 2.0).

From what I understand, this is how it works :

  1. The user open the app and provides his login credentials.
  2. App makes a POST request to the server and the server issues an access token (random, unguessable token) to the app.
  3. The app stores this access token securely on the local storage (sqlite db/shared preferences etc.) and uses sends this token with every other API call to let the server know that it is authorized to access the resource.
  4. Now this access token has an expiry time as well. So that even if the access token gets compromised, somehow, the attack window would be small.
  5. Now when this happens, it would require the user to renter his login credentials and obtain an authorized access token again, which at least in case of mobile apps, is a bad (not acceptable) user experience.
  6. So to solve this problem, there is a refresh token that is also issued to the app along with the access token in the first place. This refresh token is a very long lived special token, which makes sure that as soon as the access token expires, it requests the server for a new access token, thus removing the need for the user to re-enter his login credentials to retrieve a new authorized access token.

Now my question is:

how does this solve our original problem of preventing unauthorized access to the APIs ? In my opinion, it actually facilitates it further.

If the access token gets compromised, it's highly likely that the refresh token would also get compromised the same way, isn't it? And because the refresh token is a very long lived token, the attacker would be able to use it (till the refresh token does not expire) to keep generating new authorized access tokens. Is that correct ?

Please help me understand this.

3
  • Client_id and client_secret are also required with refresh tokens, right?
    – pri
    Feb 10, 2016 at 10:43
  • Well yes, in the classic usage of OAuth 2.0, it should be required I guess. However, that would make sense in the case when we are exposing our APIs to third party developers. However, in case of our own mobile application which will be used by huge number of customers, it's not really used and instead the authorized access token is given on successful login.
    – qre0ct
    Feb 10, 2016 at 11:13
  • @PriyankGupta No. There are two parameters to the refresh access token POST: grant_type, which value must be refresh_token, there is a refresh_token parameter, and finally, an optional scope. No client_id or client_secret when renewing an access token. See tools.ietf.org/html/rfc6749#section-6 Aug 25, 2017 at 22:54

1 Answer 1

27

The main advantage of a refresh token is that it is easier to detect if it is compromised.

Consider these two scenarios:

  1. A single long-lasting auth token is used.
  2. A short duration auth token is used, and a long-lasting refresh token periodically requests a new auth token once the previous one has expired.

In scenario 1, if the auth token is compromised it would be hard for anyone to detect this, and the unauthorized access could continue indefinitely.

In scenario 2, if only the auth token is compromised (refresh token is not compromised too), it could only continue until the token expires.

In scenario 2, if the refresh token is compromised, once the refresh token is invoked, all other auth tokens that were generated using that refresh token are invalidated, so only 1 party can use the api (per refresh token) at a time. This results in multiple users repeatedly invalidating each other's auth tokens by generating new ones. The api could detect the breach because refreshes are being made prior to the auth token expiration, and would know to immediately revoke the refresh token.

14
  • The last paragraph of your answer was a little confusing, esp. the part "This results in multiple users repeatedly invalidating each other's auth tokens by generating new ones". Would really appreciate if you could please elaborate a little on this?
    – qre0ct
    Feb 11, 2016 at 16:47
  • 4
    @geek_ji. Sure: it works like this: There is only 1 valid Auth token at any time (per refresh token). When the refresh token is used to get a new Auth token, all existing Auth tokens are invalidated, and a new one is handed out. If User 1 uses the refresh token to get a new Auth token, and now user 2 users the same refresh token to get a new Auth token, User 1's Auth token is no longer valid. User 1 now has to use the refresh token again to get a new Auth token, but in doing so invalidates User 2's token, etc. They are fighting over the auth token, and the API could detect it.
    – TTT
    Feb 11, 2016 at 16:55
  • I tried to fit that explanation into a single comment. I'm not sure if that was any clearer... :D.
    – TTT
    Feb 11, 2016 at 16:57
  • Great. I incorporated part of the explanation into the answer to make it clearer.
    – TTT
    Feb 11, 2016 at 19:16
  • 1
    On second thoughts, I am still a little confused. I also went through security.stackexchange.com/questions/87119/… for an understanding. We seem to be making a lot of assumptions here, like 1. the authorization server and resource servers are decoupled entities (which is not mandatory as per OAuth 2.0 principles, AFAIK) 2. The refresh token is strictly always exchanged with the authorization server alone and the connection between client and auth server is strictly HTTPS and the auth server is relatively uncompromisable.
    – qre0ct
    Feb 12, 2016 at 6:59

Not the answer you're looking for? Browse other questions tagged .