On the rfc https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-12#page-40 , you can see a sentence saying "Removed 'expired_token' error code."
That is, "invalid_token" will be used for expired token cases.
Why was that? I think it was very useful for the client to distinguish an expired token and an invalid token. Without "expired_token", how can the client decide whether to refresh an access token?
It was removed to prevent potential security leaks of information that attackers might use.
Let's say an attacker can get a copy of your Access Token by sniffing all of your network traffic. But the attacker only analyzes this information after your token has expired. If the attacker tries to make requests to your service with that token, and receives back an 'expired_token' code, they know that they are onto the right thing, and just need to get a later copy.
If the attacker, however, receives back an 'invalid_token' message, it makes it more difficult for the attacker to understand that the data they had WAS an access token (maybe it was something else?).
Furthermore, the way access / refresh tokens typically work, is something like this:
A client needs to make an API request and has an access token and a refresh token.
The client makes a request to the API service with their access token and gets an 'invalid_token' message.
The client locally validates their refresh token, sees it is still valid.
The client then submits a refresh request using their refresh token, and gets a new access token.
If the client locally validates their fresh token above, and gets an error (maybe the token expired, or something), they know they need to re-authenticate the user FRESH to receive both a new refresh AND access token.
The same is true if, when the user submits their refresh request, their refresh token is considered invalid (maybe the server-side revoked this token?).
Related
As we know that access token gives the client to access resources from resource server, I would like to know the contents and the process that happens with refresh token to get new access token.
I was tryging to experiment how oauth2 works, but got stuck at what refresh token does.
I would like to know the contents and the process that happens with
refresh token to get new access token.
Refresh token are generally opaque token (random unique string).
Refresh token is used to get new access token from the Authorization Server. Refresh tokens typically remain valid for longer time as compared to access token. In a typical client-server flow, when the access token expired, server reject the request then client uses the earlier obtained refresh token to get a new access token from Authorization Server. By doing so authentication between client and server remain uninterrupted and no re-authentication needed. Once the refresh token expired, client has to go through the complete authentication flow which usually require user intervention.
I see most of people saying when we use refresh token to exchange for a new access token, the auth server would issue a new refresh token and invalid the previous one. Refer
OAuth Refresh Token Best Practice
But from the OAuth website
https://www.oauth.com/oauth2-servers/access-tokens/refreshing-access-tokens/
It says the auth server can "optionally issue a new fresh token in response, or if we don't include a new refresh token, the client assumes the current refresh token will continue to be valid"
So, it looks like both options (keep or renew refresh token) are acceptable to OAuth2 standard.
My questions are:
1) Do both options are equally secure?
2) If the auth server returns a new refresh token but the client fails to receive (e.g. network error), the client has no way to re-gain access token with existing refresh token, which already invalidated. Correct?
3) If the refresh token has been leaked to someone else, both the attacker and the victim client can use it. If the auth server takes the renewal approach, then only the first one to use the refresh token can re-gain access token. So, if the victim found the refresh token is no longer valid, it may think that the refresh token has been compromised. Is this the reason for the "renewal approach"?
2.) Yes, that's correct.
3.) That's correct too. You can take a look at the OAuth 2.0 for Browser-Based Apps RFC which discusses the refresh token regeneration. It's important mainly for public clients - the ones without client_secret, since a refresh token can be exchanged for an access token right away.
1.) Refresh token regeneration is a security feature - it shortens validity of a stolen refresh token and it enables the auth server to detect that refresh token had been compromised. So it's more secure to use it than not. But it may be more convenient for private clients not to get a new refresh token on each use - for example to prevent the refresh token loss due to network error - as you described it in point #2.
In the answer to the question Why do access tokens expire?, the first point provided states:
[Bearer-Tokens are] short-lived and requiring refresh, they limit the time an attacker can abuse a stolen token.
But when an Access-Token is used (From a native-app), the Client uses the Refresh-Token to get a new Access Token, and sends that new token back to the requestor. So if an attacker uses somebody else's access token, he'll just be sent a brand new access token every time.
So who cares about how long the token lasts? If an attacker gets it, they have taken over the session For As Long As The Refresh Token Lasts
I already know a dozen answers to my question, but I have questions to each answer. My original question was so long because I explained every scenario and how they are inconsequential or false (as far as I know). So please try to help me understand and I'll comment if I think the answer has caveats.
Addition/Edit - Hoping for more answers with my additional information
Web Page calls a Client with Resource Owner (User) Credentials
Client calls the Auth Server and gets an Access and Refresh Token. The Access Token will expire in 5 minutes, the Refresh Token will expire in hours or days or whatever.
Client sends the Access Token to the Web Page
Resource Owner (User) uses the web page
Web Page sends the Access Token to the Client
Client sends the Access Token to the Resource Server
Resource Server checks the Access Token in any number of ways
Resource Server sends Resources to the Client
Client sends Resources to the Resource Owner
Resource Owner (user) Continues to use the Web Page
The Client, either during Each Request or every 4 minutes and 30 seconds, uses the Refresh Token to get a new Access Token
The Client, either during Each Request or every 4 minutes and 30 seconds, sends a New Access Token to the Active Resource Owner
Yes? No? Since the Resource Owner is Actively using the web site, the web site is in constant communication with the Client, and the Client gets a new Access Token (Using the Refresh Token) and sends it back to the web site, so the Active user can continue using the site without being kicked out every 5 minutes.
Therefore, if ANY Person gets ahold of that Access Token, and are hitting the Client with it, the Client will continue to send new Access Tokens to whoever has that Access Token. Granted: After a single refresh, one of those two people will have a bad Access Token and be booted, but not necessarily the right person.
Your point seems to be that if an attacker can take over your browser session then they will be able to access the third-party resource for the entire length of the refresh token, as you've described. So what's the point of having a short-lived access token?
There's certainly some truth to that, but there are two general responses:
Using a refresh token makes it practicable to invalidate the user if the third-party figures out that the session has been taken over by an attacker.
The access token / refresh token system is used to prevent or limit other kinds of attacks that you haven't mentioned.
Regarding the first point, remember that the access token is sent to the resource server, not the authorization server. Although there's nothing in the specification that prevents the resource server from checking the validity of the user, in practice that could present performance issues. Access tokens are typically designed to be self-validating, without requiring access to some external resource.
Given that, the only way to invalidate a user is to do it on the authorization server when the refresh token is sent in. The authorization server sees that this user has been marked as compromised, and refuses to send a new access token.
Regarding the second point, there are plenty of other security scenarios that OAuth is designed to protect against other than a user's browser session being taken over by an attacker. What if someone is able to get ahold of the access token in some other way? Since the access token itself isn't generally used to get access to the client (see below), they won't be able to get the client to refresh the token for them, and therefore the fact that the access token is short-lived will be a security advantage.
As a reference, both of these points are made succinctly in this email to the Oauth Working Group mailing list.
Looking specifically at the flow you described in your post, I think your confusion is rooted in the idea that the client (web server) sends the user agent (the browser) the access token (your step 3), and that that token (in the form of a cookie) is what the client uses to authenticate the user agent. Although it's possible for a web framework to do those things, neither one is a part of OAuth (nor generally true of web frameworks, in my experience).
Access tokens are short-lived, refresh tokens are long-lived. Access tokens are presented to the Resource Server (and only the Resource Server) that hosts the protected content to get access. Refresh tokens are presented only to the Authorization Server, never to the Resource Server. So when an attacker obtains an access token, he can use it for the lifetime of the access token to get access to the protected content.
When the access token expires there's no way to get a new one unless he has obtained the refresh token as well. Besides that, when using the refresh token the client typically authenticates itself to the Authorization Server, so even when the attacker got the refresh token, he would also need the Client's credentials to use it to get a new access token.
maybe i'm misunderstanding the authorization code grant type, but i thought that after issuing a code spring will keep the code in oauth_code table in DB forever till it will be revoked by user , but the code is deleted right after it is consumed (first time you exchange this for token),
so what is the flow here - should my clients keep the refresh tokens for getting access token later on (or when user is offline)
the spec say the return of refresh tokens is optional as written
The authorization server authenticates the client, validates the
authorization code, and ensures that the redirection URI
received matches the URI used to redirect the client in
step (C). If valid, the authorization server responds back with
an access token and, optionally, a refresh token.
so it the authorization server decide not to give refresh token there is no way for clients to offline request access token and they need to go though the authorization code process all over again ?
thanks
Shlomi
The authorization code can only be used once, and it must have a short lifetime. If you read section 4.1.2 of the spec it says
The authorization code MUST expire
shortly after it is issued to mitigate the risk of leaks. A
maximum authorization code lifetime of 10 minutes is
RECOMMENDED.
So once a code has been used there is not real reason to retain it (other than possibly to detect further attempts to use it).
The refresh token allows the client to obtain another access token. Otherwise, as you say, it needs to re-execute the authorization code flow to get one from scratch, which requires the interaction of the resource owner (the user). Usually the system would be set up to issue a refresh token or not to that client depending on whether it actually requires offline access to the resource, or whether the resource owner (user) will always be interating with it directly.
Say I'm developing an Evernote or YouTube client, and after the user logs in, the app gets an authorization token from the API server.
Then I use this token to interact with the server until, sometime later, the token expires.
The key is, I don't know if this token is expired until the server returns an error with a message like 'token expired'. Then I have to fetch a new token. Maybe it occurs while the user is posting a message.
So what is an elegant way to deal with this scenario? I want to combine fetching a new token with continuing the last request, so that the user just feels it works as usual.
It depends on which flow you're using. But in general, if you are able to refresh the auth token (via refresh token) without redirecting the user for credentials again, you should do it seamlessly.
Also, you should know exactly when a token is going to expire. If you're coding against an OAuth 2 implementation, the auth token response should give you an 'expires_in' field as a time span telling you exactly how long the token will expire after it was issued to you.