I'm using JWTs for authenticating users for my app. When a user logs in they are given an access token and a refresh token. To keep the refresh token safe, I don't store it on the client-side, but save it on the back-end with their account so it's not easy to access. I'm confused about the security of refresh tokens though, here's the logic that I'm understanding when I read online resources on how to use refresh tokens:
The security issue I'm worried about is if someone else (hacker) got a hold of the access token and they send a request to the api with it, if the token is expired the api will use the refresh token to get a new access token + new refresh token and return at least the access token to the hacker.
I read this article about 5-6 times and I read this article a few times, as well as some other articles on the subject, they all say something along the lines of
make sure to store the refresh token securely because it's long lived, the access_token is short lived so not as big of a deal
But according to the flow I described above, it doesn't matter if the access token is short lived, the refresh token will be used to get a new access token and have access forever.
Is there something I'm missing? How would the api know who is sending the request if a hacker got a hold of the expired access token? it will still send a new one using the refresh token. Am I supposed to somehow validate who is sending the request?
UPDATE
So I do understand that when a new access token is requested, I need to send over the refresh token, the client ID, and the client secret. The issue I have with that is, like before, the hacker can send a request to my API server, the server gets the hijacked access token from the hacker, it will see that it's expired, so it will send the refresh token, along with the clientID/client secret (which are stored as environment variables) to the Auth API and get back a new access token / refresh token, which brings us back to the same issue.
UPDATE 2
some interesting questions on the subject:
according to the second question and answer, it seems like the refresh token is not a more secure way to maintain access, it's just that it's easier to detect a hacker because auth/refresh tokens keep getting requested and invalidating the other's tokens. The issue with this is this will only happen if 2 users are simultaneously trying to access resources - if only the hacker happens to be active at a given time period, he will have unlimited access to the original users data until the original user tries to use the app and access protected resources
The refresh token is used to authenticate the user after the initial access token has expired. This happens behind the scenes without user interaction, facilitating an improved user experience without compromising security. Refresh tokens do not give the user any additional access beyond what was originally allowed.
OAuth access tokens and refresh tokens should be encrypted and stored in a secure database. Your application should use a strong encryption standard such as AES. The production encryption keys should not be accessible to database administrators, business analysts, developers, or anyone who does not need them.
The authorization server can contain this risk by detecting refresh token reuse using refresh token rotation. If your application uses refresh token rotation, it can now store it in local storage or browser memory.
now as long as the user doesnt do a hard refresh or navigate away from your site, they can be logged in forever.
I'm not an expert on all the intricacies of the different tokens, their mechanisms, and their storage best practices (so refer to other articles/experts on the subject - Tim Hardy poses an excellent and strong counterargument to my findings in the comments below) but it seems like a bad idea to use refresh tokens with browser based apps. Refresh tokens can be stored securely on phones/other devices. You could potentially use an http only cookie in a browser or store the token in memory (see more below) but again, I'm not certain on the security of this approach (I'm not saying its NOT secure, I'm saying I don't know how secure)
while (again) I personally dont know the full extent of risks involved with storing access/refresh tokens in browser storage (besides XSS attacks), you have a couple relatively safe options here.
Either store a long-lived access token ONLY in-memory, or use a combination of a short-lived access token (in-memory or localstorage is safe too probably since its short-lived) plus a refresh token ONLY in-memory. This approach allows the user to be logged in forever as long as they dont refresh the page or navigate away.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With