guest@mukunda.com:/blog# ./cat 2023/refreshing-access-tokens.txt Name: Refreshing Access Tokens Date: 1/12/23 I've found myself with a short battle justifying the complexity that is the Oauth2 refresh strategy. If you do a quick search on it, you'll find a handful of controversy discussing whether it is worth the added authentication complexity at all. One argument is application performance. For example, you should not store a refresh token in the database in plain text, since that might get compromised. Hashing takes time, especially password hashing, which can consume a ton of resources if you are regularly refreshing tokens. However, refresh tokens are not passwords, so you can use a cheap algorithm like a simple sha-256 which will quite possibly never be broken considering you are hashing a long string rather than a short password. Another argument is the access token getting leaked since it is 'used regularly', but honestly I don't know how someone is going to leak only their access token and not the refresh token which is right next to it. So, why have refresh tokens at all? Why not just have a long lived access token? You technically can do this with the existing OAuth2 specification - you just issue a long expiry time for the access token and omit the refresh token. However, I've come up with one reason to keep refresh tokens, and that is the feedback you will get when someone logs you out or stops your service from working. With that scenario in mind, it is important to change the refresh token every time it is used. A lot of implementations of OAuth2 do not do that, keeping the same refresh token persisting until expiry. Example 1: Someone sneaks onto your workstation physically and makes a copy of your refresh token cookie. Now you both have it and both can generate access tokens. It's hard to notice someone is using it at the same time (IP checks aside). Example 2: Someone steals your refresh token, but they can only be used once. - Chances are you will get back to work and refresh the token before the attacker can even do anything with it. - If they do use it to get an access token, then YOU will get logged out, and that is something you can act on. If you are a user that is paranoid enough, you can revoke all tokens if you notice an odd event like that. So, a little more secure with that in mind, when you don't persist a single refresh token value. Invalidating previous access tokens is another concern, but I think that's not worth the headache -- it's already bad enough when the refresh token is changing and you need to synchronize authentication requests between a service cluster. Update: I also looked through the OAuth 2.0 specification, and they mention similar reasoning. However, they also bring up a great point that refresh token misuse can be detected by the server, thereby making it much more actionable: https://www.rfc-editor.org/rfc/rfc6749#section-10.4 If a refresh token is compromised and subsequently used by both the attacker and the legitimate client, one of them will present an invalidated refresh token, which will inform the authorization server of the breach. Send the author a comment << Index