Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Refresh Token Rotation - is it really enough?

In the context of a Single-Page Application (JavaScript) authenticating with an OIDC Server, the standard and recommended way to keep the session alive (getting more tokens after they expire) is to use a HttpOnly Cookie and perform a Silent Renew within an iframe. Great, no Refresh Tokens involved since the browser cannot keep a secret.

It seems now that the browsers are going to prevent Cross-origin Cookies (Safari and Brave already do, Chrome will be next it seems), so if the Server is on a different domain it appears that the only way in the future will be to use Refresh Tokens with Refresh Token Rotation (and possibly Reuse Detection) which seems to mitigate the problems. But does it really?

Scenario 1) Refresh Token (RT1) is stolen, user requests a new token and gets back a new Refresh Token too (RT2) because of rotation. RT1 is now invalid and cannot be used by the attacker. Great.

Scenario 2) Refresh Token (RT1) is stolen, the attacker performs a request to get a new token (RT2), user uses the old token (RT1) and now everything is discarded and the user has to login again (Reuse Detection) and the attacker's token is invalid too. Great. Well I kinda see a problem here (the user has to login again and doesn't know why) but at least the problem is solved.

Scenario 3) This is the scenario I don't see mentioned anywhere. Suppose the attacker is stealing every subsequent RT without using them, so it proceeds to steal RT1. User refreshes, and attacker steals RT2 too. Everything is working fine because the attacker hasn't used the token, but maybe he sent all tokens somewhere else to be stored. At the end, the user closes the window and the attacker has extracted both RT1, and RT2. At this point, the attacker can use the latest RT (RT2) to impersonate the user until the user comes back to the app. Say he stays away for a week, the attacker has new Access Tokens for a week (he can continuously refresh the tokens). Nobody notices anything until the end. With a Cookie, the attacker could operate only during the browser session, now it has much more time for that.

So... is RTR with Reuse Detection really secure enough? The main argument is "it's always a risk/benefit choice", I get it, but how can it be 2020 and we're still having troubles with browsers? Do you see anything wrong with the 3rd Scenario that I'm missing? Honestly, session cookies has always been the best choice, the fact that browsers are going to prevent us from using them for this common scenario drives me nuts :)

Thanks.

PS. I'll copy here some resources I find about this problem:

  • https://pragmaticwebsecurity.com/articles/oauthoidc/refresh-token-protection-implications.html

"RTR is not a catch-all security measure. If an attacker manages to obtain the last refresh token before the app closes, they might be able to keep rotating the stolen refresh token. To avoid long-term abuse of a stolen refresh token, the security token service can link the lifetime of that refresh token to the lifetime of the user’s session with the security token service. Doing so would invalidate the refresh token when the session expires."

This is the point I made in scenario 3, but the solution he suggests is to link the RT to the user's session. So, we're using Session Cookies again, aren't we? What if we cannot use them? RTs in this scenario should be an alternative for when we cannot use cross-domain cookies.

  • https://leastprivilege.com/2020/03/31/spas-are-dead/

This one seems to agree with me on that RTs even with RTR are not secure enough and the SPA would need to be connected to a backend on the same domain in order to work as before.

like image 436
Michele Stieven Avatar asked Nov 06 '20 02:11

Michele Stieven


People also ask

Is refresh token rotation secure?

When a client needs a new access token, it sends the refresh token with the request to Auth0 to get a new token pair. As soon as the new pair is issued by Auth0, the refresh token used in the request is invalidated. This safeguards your app from replay attacks resulting from compromised tokens.

How long should my refresh token last?

The Refresh token has a sliding window that is valid for 14 days and refresh token's validity is for 90 days.

How often should you refresh access token?

Realistically, you should wait at least 10 minutes between refreshes, because it's not possible for sessions to expire sooner than 15 minutes (other than being manually expired/logged out).

Are refresh tokens insecure?

Introducing Refresh Token Rotation As previously mentioned, using RTs in SPAs was considered insecure because they typically have long lifetimes (hence, their use in retrieving new short-lived ATs) and browser storage is susceptible to token theft.


1 Answers

Interesting area this, and it is often a trade off between Usability, Security, Performance and Cost. The current state of the industry is pretty unsatisfactory, but I hope some of this helps you to understand the main issues.

REFRESH TOKENS IN THE BROWSER

Before using this solution I would ensure that the Authorization Server properly supported the OAuth 2.1 RTP recommendations - not many Authorization Servers do.

I would then ensure that I only stored refresh tokens in the app's memory, since it is not recommended to store tokens in local storage. This then means that:

  • Multi tab browsing or reloading a page will require a token refresh via the older iframe based solution you mention
  • This will not work silently in Safari so there will be a browser redirect which usability stakeholders are likely to complain about

SECURITY ASPECTS

Your SPA security is about more than just token mechanics of course. You need to ensure that security stakeholders accept the solution, and you need to think about threats such as what an attacker can do with a token / cookie.

BACK END FOR FRONT END PATTERN

One of the big problems with this is that you typically need a back end that issues same domain HTTP only encrypted cookies, coded in C#, Node, Java etc.

This can be very intrusive for an SPA architecture:

  • Pushing web static content to many global locations via a Content Delivery Network is either not possible or more difficult
  • You may require double hops on every API call from the SPA, which adds complexity, especially around areas such as caching and API error responses
  • Security is not 'solved' by using auth cookies, and many browser threats still need to be dealt with

2022 UPDATE

These days I would recommend keeping tokens out of the browser, since this is now perceived poorly. Maybe have a look at the Token Handler Pattern as a modern solution.

like image 106
Gary Archer Avatar answered Sep 30 '22 08:09

Gary Archer