Subject: [OAUTH-WG] Token refresh and The Two Generals

From: Bob Gregory <[email-masked]>
Date: Fri, 23 Nov 2012 12:43:21 +0000

We've had OAuth2 running successfully for a while now, but we're finding
that mobile applications have frequent problems with the refresh flow where
a refresh request is made, but the network connection fails before the new
AT/RT pair is received, leading to a "lost grant".

In server-logs we can see that the token has been refreshed, and a new RT
issued, but the client is stuck with the old invalidated RT.

This problem has been reported by two separate client applications, both of
whom are using a retry-mechanism for API requests since they expect an
unreliable network connection.

Does anybody have any guidance on this issue, or is there any work in an
extension to address the issue of lost grants for token refreshes?

-- 
Q. How many members of a demographic group does it take to perform a
specified task?
A. A finite number; one to perform the task, and the remainder to act in a
manner stereotypical of the group in question.

---

From: Sergey Beryozkin <[email-masked]>
Date: Mon, 26 Nov 2012 09:53:46 +0000

On 23/11/12 12:43, Bob Gregory wrote:
> that mobile applications have frequent problems with the refresh flow
> where a refresh request is made, but the network connection fails before
> the new AT/RT pair is received, leading to a "lost grant".
>
> In server-logs we can see that the token has been refreshed, and a new
> RT issued, but the client is stuck with the old invalidated RT.
>
> This problem has been reported by two separate client applications, both
> of whom are using a retry-mechanism for API requests since they expect
> an unreliable network connection.
>

I wonder if a RM support is needed at the transport/protocol level for 
this to work reliably ?

The same issue would also arise when an authorization code grant which 
is expected to be used only once is validated on the server and a new 
access token has not made it back to the client due to a connection loss...

Sergey

> A. A finite number; one to perform the task, and the remainder to act in
> a manner stereotypical of the group in question.
>
>
>
> _______________________________________________
> OAuth mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/oauth

---

From: Sergey Beryozkin <[email-masked]>
Date: Mon, 26 Nov 2012 11:46:55 +0000

Hi Bob,
On 26/11/12 10:47, Bob Gregory wrote:
> Hi Sergey,
>
> We are less concerned about failure during the initial authorization,
> since an end-user might reasonably expect to be asked to sign in again
> if a failure occurs.

Indeed

> What's awkward here is that the user has been
> successfully using the application for some time, and - from their
> perspective - is suddenly signed out for no obvious reason.
>
I guess the issue can be treated in principle the same as if a client 
has had its current access token expired and no refresh token has been 
provided, which I guess has to be dealt the same way when an 
authorization code grant has been lost, as you suggested above...

I'd consider some sort of RM support really helping to mitigate, but I 
may be wrong :-)

Sergey

> Can anybody with experience in deploying OAuth2 for mobile applications
> proffer advice? We can't be the only people seeing this, so I wonder if
> other implementers are mitigating the problem somehow.
>
> -- Bob Gregory
>
>
> On Mon, Nov 26, 2012 at 9:53 AM, Sergey Beryozkin <[email-masked]
> <mailto:[email-masked]>> wrote:
>
>      > [email-masked] <mailto:[email-masked]>
>     [email-masked] <mailto:[email-masked]>
> Bob Gregory  |  Application Architect | Huddle – manage projects, files
> and people in the cloud
>
> Email: [email-masked] <mailto:[email-masked]> | Skype: flinkywistypomm
> Web: www.huddle.com <http://www.huddle.com> | Blog: blog.huddle.net
> <http://blog.huddle.net> | Twitter: @bobfromhuddle
>
> UK office: Unit B, Gemini House, 180 Bermondsey Street, London, SE1 3TQ
> US office: 425 Bush Street, Suite 435, San Francisco CA 94108
>
> Free Huddle trial! Sign up for a 14-day free trial and find out why
> 85,000 businesses use Huddle
>

---

From: Brian Eaton <[email-masked]>
Date: Mon, 26 Nov 2012 18:27:22 -0800

On Fri, Nov 23, 2012 at 4:43 AM, Bob Gregory <[email-masked]> wrote:

> of whom are using a retry-mechanism for API requests since they expect an

Have you considered not revoking the old RT until the new RT has been
successfully used?

You might also need to consider what happens with requests that are
in-flight at the time the old RT is revoked.  For example:

1) client starts token exchange, hangs for some reason.
2) client starts token exchange, succeeds, receives new refresh token
3) client uses new refresh token
4) request 1 completes

That could all happen in the space of a second or two.  So you might want
to think about not revoking the old token until you see the new refresh
token used and a bit of time has passed.

Cheers,
Brian

---

From: Tim Bray <[email-masked]>
Date: Mon, 26 Nov 2012 18:48:12 -0800

As I read back through this one I’m not getting why you need a new refresh
token.  What am I missing?  -T

---

From: Shane B Weeden <[email-masked]>
Date: Tue, 27 Nov 2012 13:22:42 +1000

My understanding is that it is considered a best practice to rollover a
refresh token on each use - that is when a refresh token is used, both a
new access token and a new refresh token are issued, and the old refresh
token is revoked.

The primary reason I have seen cited for this is it would allow for the
detection of a compromised refresh token (cloned client for example). If
the legitimate client is not the first to use their refresh token it will
fail when they do eventually try to use it. The likelihood of such a
scenario or other implications of a lost refresh token is a different
debate.

Ideally the timeouts on the messages and the transport used for the refresh
token exchange should be "reliable". If that is not the case then a
mechanism such as suggested by Brian is possible, but ultimately not very
clean as it means you really need to maintain at least two valid refresh
tokens concurrently per initial grant and it gets messy. For example
extending Brian's scenario, what would you do in response to #4? Return the
same refresh token as #2? Return a new one and invalidate the one returned
in response #2? From a server-side perspective you don't really know what
the "right" thing to do is as you don't know the true state of the client.

I would be inclined to optomise for the normal case and provided the error
rate wasn't too high simply require a new initial grant when the app's
refresh token gets out of sync.
If the error rate is very high then I would consider a
non-OAuth-standards-based more reliable transport mechanism for refresh
token flows from the mobile, perhaps with a trusted piece of intermediary
infrastructure to interface with the real authorization server using a
standard flow.

Regards,
Shane.

From:	Tim Bray <[email-masked]>
To:	Brian Eaton <[email-masked]>
Cc:	OAuth WG <[email-masked]>, Bob Gregory <[email-masked]>
Date:	27/11/2012 12:53 PM
Subject:	Re: [OAUTH-WG] Token refresh and The Two Generals
Sent by:	[email-masked]

  On Fri, Nov 23, 2012 at 4:43 AM, Bob Gregory <[email-masked]>
  wrote:

  Cheers,
  Brian

---

From: Bob Gregory <[email-masked]>
Date: Tue, 27 Nov 2012 12:28:35 +0000

We did consider holding on to two refresh tokens, but it rapidly gets messy
and degrades to using a single refresh token: since the old token won't be
invalidated until the new one is used, a client can continue to use the old
token indefinitely.

After hurried conversation, we've decided that we will allow mobile clients
to use a long-lived refresh token that does not expire on each request.
This isn't our preferred option, since we have no way of detecting a
compromised RT, but in order to obtain the RT an attacker must either

a) Intercept the token in-flight by a MITM attack over SSL, which is
non-trivial, or
b) Obtain physical access to the client device, in which case it's game
over anyway.

We'll probably revisit this decision when we come to do another round of
work on authentication, but for now this solves a user-experience issue
that we're seeing in the wild, without seriously affecting real-world
security.

Thanks for your comments, I'll let you know if we find a way to de-messify
the two-token solution.

Yours,

 -- Bob.

---

From: Brian Eaton <[email-masked]>
Date: Tue, 27 Nov 2012 12:10:22 -0800

> new access token and a new refresh token are issued, and the old refresh

FWIW, I think rotating the refresh token every time it is used is a bit
excessive, something time based (e.g. once every few weeks or few months)
would be fine as well.

The trade-off is that things that happen rarely are more likely to trigger
bugs on the client side. =)

---

From: Shane B Weeden <[email-masked]>
Date: Wed, 28 Nov 2012 07:16:47 +1000

Sounds like a sensible approach Bob - and thanks for the discussion as it's
real-world issues like this which ultimately really matter.

From:	Bob Gregory <[email-masked]>
To:	Shane B Weeden/Australia/IBM@IBMAU
Cc:	Tim Bray <[email-masked]>, Brian Eaton <[email-masked]>,
            OAuth WG <[email-masked]>, [email-masked]
Date:	27/11/2012 10:33 PM
Subject:	Re: [OAUTH-WG] Token refresh and The Two Generals

Yours,

 -- Bob.

On Tue, Nov 27, 2012 at 3:22 AM, Shane B Weeden <[email-masked]>
wrote:
  My understanding is that it is considered a best practice to rollover a
  refresh token on each use - that is when a refresh token is used, both a
  new access token and a new refresh token are issued, and the old refresh
  token is revoked.

  Ideally the timeouts on the messages and the transport used for the
  refresh
  token exchange should be "reliable". If that is not the case then a
  mechanism such as suggested by Brian is possible, but ultimately not very
  clean as it means you really need to maintain at least two valid refresh
  tokens concurrently per initial grant and it gets messy. For example
  extending Brian's scenario, what would you do in response to #4? Return
  the
  same refresh token as #2? Return a new one and invalidate the one
  returned
  in response #2? From a server-side perspective you don't really know what
  the "right" thing to do is as you don't know the true state of the
  client.

  I would be inclined to optomise for the normal case and provided the
  error

  Regards,
  Shane.

  As I read back through this one I’m not getting why you need a new
  refresh
  token.  What am I missing?  -T

  On Mon, Nov 26, 2012 at 6:27 PM, Brian Eaton <[email-masked]> wrote:
    On Fri, Nov 23, 2012 at 4:43 AM, Bob Gregory <[email-masked]>
    wrote:
     We've had OAuth2 running successfully for a while now, but we're
  finding
     that mobile applications have frequent problems with the refresh flow
     where a refresh request is made, but the network connection fails
  before
     the new AT/RT pair is received, leading to a "lost grant".

     This problem has been reported by two separate client applications,
  both
     of whom are using a retry-mechanism for API requests since they expect
     an unreliable network connection.

     Does anybody have any guidance on this issue, or is there any work in
  an
     extension to address the issue of lost grants for token refreshes?

    That could all happen in the space of a second or two.  So you might
  want
    to think about not revoking the old token until you see the new refresh
    token used and a bit of time has passed.

    Cheers,
    Brian

---

From: Bob Gregory <[email-masked]>
Date: Tue, 27 Nov 2012 22:07:35 +0000

Actually, this is one of the approaches we've considered. This issue most
commonly occurs when an end-user is moving from 3G to wi-fi, or from an
active mobile connection to a zero-signal area.

If we recycle refresh tokens less frequently (after, say, 24 hours) then
the client application will be able to retry the refresh once their
connection is reliable again, but we keep most of the advantage of
refresh-token revocation. The trade-off is that it's more of a pain to
build this way, and we're in an awful hurry :)

-- Bob

On Tue, Nov 27, 2012 at 8:10 PM, Brian Eaton <[email-masked]> wrote:

> On Mon, Nov 26, 2012 at 7:22 PM, Shane B Weeden <[email-masked]>wrote:
>