30

I'm trying to add authentication feature to my application. The authentication server implements oauth 2.0

I'm not sure how to save the refresh_token. I want to save it to a file, so next time when the application starts and there is a refresh_token available, it can ask for a new access_token. The user won't need to re-login again.

But this doesn't sound secure to me, because if someone copies my file that has the refresh_token to another computer, he can hack into my account.

prasad_
  • 12,755
  • 2
  • 24
  • 36
Bill Yan
  • 3,369
  • 4
  • 27
  • 42

3 Answers3

14

You are correct with the attack that you describe. Refresh tokens have to be stored securely in order to be used as intended. As I understand, you are building a standalone application. Therefore, you can rely on file system security to prevent a refresh token being copied by an unauthorized user. You may want to use encryption for the refresh token, too, but the key would need to be bound to a user's session at your local machine (otherwise, the user would need to provide it during "sign in" process in order for the application to decrypt the refresh token).

Consider reading the thread from the OAuth WG, that discusses similar problems to the one described and provides some guidance: https://www.ietf.org/mail-archive/web/oauth/current/msg02292.html

Jonas G. Drange
  • 8,749
  • 2
  • 27
  • 38
mmachulak
  • 379
  • 2
  • 7
  • 2
    Please take a look here https://developers.google.com/api-client-library/python/guide/aaa_oauth for a section with the following line of code: `from oauth2client.file import Storage`. When I used that code to create storage, it simply created a plain JSON file containing all of the information. One of the advantages of this class `oauth2client.file.Storage` is that it is supposedly thread-safe. However, no encryption is being used here, so I am torn. Google recommends using their libraries whenever possible to avoid "screwing things up". However, that Storage class is not doing much. Thoughts? – Leonid Jun 27 '15 at 05:46
  • refresh token still can be hijacked/intercepted.... it's easy for reverse engineer. Just don't use refresh tokens and use just access tokens with invalidation using some kind of black-list... refresh token doesn't help – Konrad Sep 24 '18 at 22:27
  • everything that's on the client is not secure – Konrad Sep 24 '18 at 22:30
11

Refresh tokens are used to obtain access (this process requires HTTP Basic Auth). So, unless user has your (id,secret) combination he can't do much about it. However, storage of refresh token must be considered very seriously.

Here's my two cents:

  1. Store your tokens in a DB

  2. Whenever you use refresh token to obtain access token reset the refresh token as well. (Oauth2.0 has this feature, you can let the refresh token unchanged too, but it's wise in terms of security perspective to keep it changing and updating the DB)

Hope this gives some insights!!

Sudip Bhandari
  • 2,165
  • 1
  • 27
  • 26
  • 1
    I'm late to the party here, but doesn't your second "cent" defeat the entire purpose of the refresh token? Resetting the refresh token would require the user to re-authenticate. – Highspeed Apr 03 '19 at 05:17
  • 1
    Resetting refresh token doesn't require reauthentication. – Sudip Bhandari Apr 03 '19 at 09:53
  • Resetting the refresh token defeats the purpose of the refresh token. The refresh token is a long-lived one so that a user can produce access tokens from it. By resetting the refresh token itself, you are actually converting the refresh token into an access token. – Tanmay Sep 10 '19 at 11:55
  • 1
    @Tanmay resetting refresh token doesn't make it access token.. this refresh step just ensures that there is no harm even if your tokens are compromised. – Sudip Bhandari Sep 11 '19 at 05:08
  • 1
    *"Resetting refresh token doesn't require reauthentication."*: Actually, it depends on the API. For eBay's API it does. For other APIs, it might not. – Lord Elrond Jan 08 '20 at 05:15
-6

You are right about your concern - you should not save the refresh token. By doing so, you jeopardize your client's data (and you know the reason; you wrote it in the question). oAuth is not supposed to work this way. You should keep the refresh token in-memory.

OhadR
  • 8,276
  • 3
  • 47
  • 53
  • 6
    But then the refresh token would be lost when it goes out of memory, and he would have to prompt the user for access before running his application again. – Jason Hall Jan 05 '13 at 02:42
  • @JasonHall True; in order to avoid asking the user for his credentials, the application designer must agree to jeopardize the user's security (if token is stolen somehow). – OhadR Jan 05 '13 at 15:26
  • 1
    You can encrypt the credentials or store them on your server and fetch them (securely) when the application starts. But if that isn't feasible then yes, you could just ask for permission whenever the app starts. – Jason Hall Jan 05 '13 at 21:50
  • 2
    Right now, I'm encrypting it and saving it into a file. I use the machine's mac address to generate the encryption key, so that when the file is copied to another computer, it can't be decrypted. But this still sounds weak. – Bill Yan Jan 06 '13 at 18:12
  • 1
    This isn't great security advice. Refresh tokens are designed to minimise the number of times a user's login credentials are sent over the wire. They are meant to be long living and stored by the client. Yes, the client's secret storage mechanism can become compromised, but so can everything on the client. You can blacklist refresh tokens from the server side if they are suspected to be compromised, forcing the user to re-authenticate. – Darcy Rayner Jan 15 '18 at 22:33