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