Why do access tokens expire?

111,373

Solution 1

This is very much implementation specific, but the general idea is to allow providers to issue short term access tokens with long term refresh tokens. Why?

  • Many providers support bearer tokens which are very weak security-wise. By making them short-lived and requiring refresh, they limit the time an attacker can abuse a stolen token.
  • Large scale deployment don't want to perform a database lookup every API call, so instead they issue self-encoded access token which can be verified by decryption. However, this also means there is no way to revoke these tokens so they are issued for a short time and must be refreshed.
  • The refresh token requires client authentication which makes it stronger. Unlike the above access tokens, it is usually implemented with a database lookup.

Solution 2

A couple of scenarios might help illustrate the purpose of access and refresh tokens and the engineering trade-offs in designing an oauth2 (or any other auth) system:

Web app scenario

In the web app scenario you have a couple of options:

  1. if you have your own session management, store both the access_token and refresh_token against your session id in session state on your session state service. When a page is requested by the user that requires you to access the resource use the access_token and if the access_token has expired use the refresh_token to get the new one.

Let's imagine that someone manages to hijack your session. The only thing that is possible is to request your pages.

  1. if you don't have session management, put the access_token in a cookie and use that as a session. Then, whenever the user requests pages from your web server send up the access_token. Your app server could refresh the access_token if need be.

Comparing 1 and 2:

In 1, access_token and refresh_token only travel over the wire on the way between the authorzation server (google in your case) and your app server. This would be done on a secure channel. A hacker could hijack the session but they would only be able to interact with your web app. In 2, the hacker could take the access_token away and form their own requests to the resources that the user has granted access to. Even if the hacker gets a hold of the access_token they will only have a short window in which they can access the resources.

Either way the refresh_token and clientid/secret are only known to the server making it impossible from the web browser to obtain long term access.

Let's imagine you are implementing oauth2 and set a long timeout on the access token:

In 1) There's not much difference here between a short and long access token since it's hidden in the app server. In 2) someone could get the access_token in the browser and then use it to directly access the user's resources for a long time.

Mobile scenario

On the mobile, there are a couple of scenarios that I know of:

  1. Store clientid/secret on the device and have the device orchestrate obtaining access to the user's resources.

  2. Use a backend app server to hold the clientid/secret and have it do the orchestration. Use the access_token as a kind of session key and pass it between the client and the app server.

Comparing 1 and 2

In 1) Once you have clientid/secret on the device they aren't secret any more. Anyone can decompile and then start acting as though they are you, with the permission of the user of course. The access_token and refresh_token are also in memory and could be accessed on a compromised device which means someone could act as your app without the user giving their credentials. In this scenario the length of the access_token makes no difference to the hackability since refresh_token is in the same place as access_token. In 2) the clientid/secret nor the refresh token are compromised. Here the length of the access_token expiry determines how long a hacker could access the users resources, should they get hold of it.

Expiry lengths

Here it depends upon what you're securing with your auth system as to how long your access_token expiry should be. If it's something particularly valuable to the user it should be short. Something less valuable, it can be longer.

Some people like google don't expire the refresh_token. Some like stackflow do. The decision on the expiry is a trade-off between user ease and security. The length of the refresh token is related to the user return length, i.e. set the refresh to how often the user returns to your app. If the refresh token doesn't expire the only way they are revoked is with an explicit revoke. Normally, a log on wouldn't revoke.

Hope that rather length post is useful.

Solution 3

In addition to the other responses:

Once obtained, Access Tokens are typically sent along with every request from Clients to protected Resource Servers. This induce a risk for access token stealing and replay (assuming of course that access tokens are of type "Bearer" (as defined in the initial RFC6750).

Examples of those risks, in real life:

  • Resource Servers generally are distributed application servers and typically have lower security levels compared to Authorization Servers (lower SSL/TLS config, less hardening, etc.). Authorization Servers on the other hand are usually considered as critical Security infrastructure and are subject to more severe hardening.

  • Access Tokens may show up in HTTP traces, logs, etc. that are collected legitimately for diagnostic purposes on the Resource Servers or clients. Those traces can be exchanged over public or semi-public places (bug tracers, service-desk, etc.).

  • Backend RS applications can be outsourced to more or less trustworthy third-parties.

The Refresh Token, on the other hand, is typically transmitted only twice over the wires, and always between the client and the Authorization Server: once when obtained by client, and once when used by client during refresh (effectively "expiring" the previous refresh token). This is a drastically limited opportunity for interception and replay.

Last thought, Refresh Tokens offer very little protection, if any, against compromised clients.

Solution 4

It is essentially a security measure. If your app is compromised, the attacker will only have access to the short-lived access token and no way to generate a new one.

Refresh tokens also expire but they are supposed to live much longer than the access token.

Share:
111,373

Related videos on Youtube

levi
Author by

levi

Updated on January 04, 2020

Comments

  • levi
    levi over 4 years

    I am just getting started working with Google API and OAuth2. When the client authorizes my app I am given a "refresh token" and a short lived "access token". Now every time the access token expires, I can POST my refresh token to Google and they will give me a new access token.

    My question is what is the purpose of the access token expiring? Why can't there just be a long lasting access token instead of the refresh token?

    Also, does the refresh token expire?

    See Using OAuth 2.0 to Access Google APIs for more info on Google OAuth2 workflow.

  • levi
    levi over 12 years
    But wouldn't the attacker also have access to the refresh token? and can than use that to create a new access token?
  • Claudio Cherubino
    Claudio Cherubino over 12 years
    You only send the access token with your requests, so an attacker will only be able to capture that. If they get your refresh token, you can still revoke it.
  • Spike
    Spike about 12 years
    @levi, the hacker cannot use the refresh token to create a new access token because the client ID and client secret are needed along with the refresh token in order to generate the new access token.
  • hansvb
    hansvb almost 12 years
    Two questions: 1) In the case of mobile apps, does the requirement for client authentication make it stronger at all? Because the client_secret is part of the application source code, so it is not at all secret. Assuming that the access token is also shared only via TLS (and your first bullet point does not apply) is there any extra security? 2) Assuming that all this holds in our scenario (only TLS, no self-encoded unrevokable tokens), is it okay to issue access tokens that don't expire?
  • Andy
    Andy almost 12 years
    @Spike True, but doesn't the app have the client id and secret embedded in it as well?
  • allyourcode
    allyourcode over 11 years
    What is a bearer token, and what does it have to do with refresh and access tokens?
  • allyourcode
    allyourcode over 11 years
    @Thilo I think the idea is that access tokens need not be revokable. As Eran points out, this makes it possible for the requested service to decide whether to service a request <em>without having to look up the access token in some database</em>. AFAICT, that is the real benefit of separating refresh tokens and access tokens.
  • Admin
    Admin about 11 years
    So it provides some protection from packet sniffing, as long as the intercept only catches ordinary data requests (Chuck only gets the access token)? That sounds a little weak; the black hat just has to wait for a bit until the user requests a new access token and then he'll get the client ID, secret, and refresh token.
  • Damon Drake
    Damon Drake almost 11 years
    This may just me being retarded here, but if this is sent over SSL doesn't that add to another possible layer of security. I guess I am assuming everyone knows what SSL is.
  • Igor Čordaš
    Igor Čordaš almost 10 years
    Yes you should use ssl with calls to get the access token. Many services even require it.
  • Amir Bar
    Amir Bar over 9 years
    about MOBILE SCENARIO it dosent matter if you store the client id in your server. so anyone else app just can send request to your server and could access the users resources throug yours server, so its the same
  • Ed Sykes
    Ed Sykes almost 9 years
    true, but then they only have access to the facilities you provide, rather than full access to the underlying token. I.e. they can impersonate your app. Often, the tokens can have broad permissions, whereas you only require a subset. Holding onto the token in the backend provides further restriction, should you need it.
  • Suamere
    Suamere over 8 years
    How is an access (bearer?) token short-lived? If I make a request with an expired bearer token, the refresh token will return a fresh bearer token. Likewise, if I steal somebody's token from their cookies, and spoof my own cookie with that token, I send it to the server, it will refresh and send me a new one. What's to stop that? Don't say IP Address or even MAC, because that's unreasonable.
  • Bon
    Bon over 8 years
    @Suamere , that was explained already. The bearer tokens are validated by a crypto process that doesn't touch the authentication database, making them much more efficient for frequent resource access. The refresh tokens are validated in a process that involves checking the database to make sure it is still valid. Now think about how gmail works. If someone logs into your account from an unexpected geographical location you can get an alert. You can see all locations that may have currently valid refresh tokens. You can log out of all locations, invalidating all those other refresh tokens.
  • Suamere
    Suamere over 8 years
    @klatzib While you're right that what you said has already been explained, and that you have good information, that doesn't remotely represent an answer to my question. If my Neighbor steals my token, s/he can send it to the provider every minute and the provider will happily refresh and give them back a new token every time. What stops that?
  • Bon
    Bon over 8 years
    What stops that is why I typed the last two sentences in my response. Invalidate a stolen refresh token and their supply of access tokens dry up as soon as those expire. The challenge is identifying aberrant behavior communicating to the user that there may be a problem requiring you to log out other locations, just like gmail does.
  • talrnu
    talrnu over 8 years
    @Suamere Refresh requests are made by the client separately from regular resource requests. The refresh token is not included in normal resource requests (resource servers can't refresh tokens!), so if the access token is stolen and then expires, the thief cannot get a new access token unless they also managed to steal the refresh token (which was only transmitted when the access token was originally acquired by the client). Even then, they'd also need the valid client credentials to refresh successfully. All based on OAuth2 docs, though as Eran mentioned, implementation may vary.
  • Suamere
    Suamere over 8 years
    @talrnu An AccessToke (AT) expiration is ~5 minutes, but whenever I make a GUI Action (Even switching pages), I get a fresh AT. Either that, or the session is kept alive with a periodic javascript "KeepAlive" HTTP Call to the web server, which constantly updates my AT. Either way, if I steal an AT, I can use one of those two mechanisms to perform actions as long as the Refresh Token on the web server doesn't expire (typically a long time). The purpose of this (these) comments is because if I'm right, point 1 of this answer is invalid. I never said anything about stealing the Refresh Token.
  • talrnu
    talrnu over 8 years
    @Suamere Are you saying your client performs a refresh request for every GUI action you take? Or are you saying every resource request your client makes returns a new token without a separate refresh request? The latter case is not compliant with OAuth 2 specification, it's something else entirely so it doesn't fit in this discussion. The former case doesn't make good use of the efficiency that intermittent refresh requests afford, but it still prevents an AT from being useful after it expires, so point 1 in the answer is valid. Or am I misunderstanding your description of your client?
  • talrnu
    talrnu over 8 years
    @Suamere By the way, in OAuth 2 the refresh token doesn't live on the web server, it's given to the client along with the AT when the client first authenticates. If your system doesn't work that way, then it's not OAuth 2.
  • Suamere
    Suamere over 8 years
    @talrnu Not as I read the spec. Client doesn't mean Resource Owner. The Resource Owner is the user of the Native-App, while client in OAuth doesn't usually mean the person logging in, but the application (Service, Server, etc) allowed to review resources or authenticate. The spec says the AT and RT get sent back to the Client. The spec purposely does not mention how or what to send to the Resource Owner, because that's an implementation detail. Some people send the Refresh Token back to the RO, Some don't. Working for very large companies, I have not yet seen an RT sent back to a cookie.
  • talrnu
    talrnu over 8 years
    @Suamere Unless I'm missing something subtle, it looks like you just described exactly what I described. I'd be happy to continue this discussion in chat if you still feel part of this answer is invalid.
  • m0s
    m0s over 7 years
    @DamonDrake SSL only covers the transport, so the likely scenario is these tokens being stolen from the clients store.
  • Marcus Vinicius Campos
    Marcus Vinicius Campos almost 5 years
    You somewhat touched on this, but I would emphasize that the larger attack surface for obtaining (or conversely inadvertently divulging) tokens is in application logs or nefariously-added resource services (not a MITM attack today). Just about everywhere in a common API backend has access to the access token used (if it has access to the HttpRequest etc object). Only TWO code paths in the system has access to the refresh token - the one that generates it in the first place, and the one that exchanges it for a new access token. That is a significant attack surface difference.