Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refresh token does not expire #6630

Closed
sdwru opened this issue Apr 7, 2020 · 10 comments
Closed

refresh token does not expire #6630

sdwru opened this issue Apr 7, 2020 · 10 comments

Comments

@sdwru
Copy link

sdwru commented Apr 7, 2020

ISSUE TYPE
  • Bug Report
SUMMARY

Using password grant type, refresh token does not expire according to REFRESH_TOKEN_EXPIRE_SECONDS.

ENVIRONMENT
  • AWX version: 10.0.0
  • AWX install method: docker on linux
  • Operating System: CentOS v8
  • Web Browser: Chrome
STEPS TO REPRODUCE

Set the expiry times low from AWX GUI > Settings > System
Confirm the settings from api

https://x.x.x.x/api/v2/settings/all/
"OAUTH2_PROVIDER": {
        "ACCESS_TOKEN_EXPIRE_SECONDS": 10,
        "REFRESH_TOKEN_EXPIRE_SECONDS": 10,
        "AUTHORIZATION_CODE_EXPIRE_SECONDS": 600
    },

Create an Application from the GUI of Authorization Grant Type Resource owner password-based. Save a copy of the clientId and clientSecret.

Create the access and refresh tokens using password grant:

curl -v -k -X POST -d \
"grant_type=password&username=someuser&password=somepassword&scope=read" \
-u "clientId:clientSecret" https://x.x.x.x/api/o/token/ -i

Which returns

{"access_token": "Ma5cLFKYs1Q8iknITJjAe0VXJyiUVP", "expires_in": 10, "token_type": "Bearer",
 "scope": "read", "refresh_token": "IymTfQp0JtT3HtDUitoAj7eaxXr3zM"}

Wait at least 20 seconds and try use refresh token

curl -k -X POST -d \
"grant_type=refresh_token&refresh_token=IymTfQp0JtT3HtDUitoAj7eaxXr3zM" \
-u "clientId:clientSecret" https://x.x.x.x/api/o/token/ -i

That previous refresh token continues to generate new access_token and new refresh_token after 20 seconds. Even after I waited 12 hours it still worked.

I also tried manually adding the settings to /etc/tower/settings.py of the docker container.

OAUTH2_PROVIDER = {'ACCESS_TOKEN_EXPIRE_SECONDS': 10,
                    'REFRESH_TOKEN_EXPIRE_SECONDS': 10,
                   'AUTHORIZATION_CODE_EXPIRE_SECONDS': 600}

and restarting the container.

EXPECTED RESULTS

The refresh token should have failed to generate a new access token and returned an error message after more than 10 + 10 seconds.

ACTUAL RESULTS

The last refresh token still generates a new access_token and new refresh_token after 20 seconds. I waited 12 hours and the last generated refresh token still works. So it appears to ignore the refresh token expiry time.

ADDITIONAL INFO

Should the refresh token stay the same each time it is used? Current behavior is that a new refresh token is generated each time it is used. The previous one no longer works. So the way it works currently, refresh tokens are one-time use only.

@ryanpetrello
Copy link
Contributor

ryanpetrello commented Apr 7, 2020

@sdwru,

In the future, we'd appreciate it if you would please refrain from publicizing issues that clearly have security implications:

image

@ryanpetrello
Copy link
Contributor

This appears to be an (unaddressed) vulnerability in Django OAuth Toolkit itself:

jazzband/django-oauth-toolkit#746

@sdwru
Copy link
Author

sdwru commented Apr 7, 2020

This appears to be an (unaddressed) vulnerability in Django OAuth Toolkit itself:

jazzband/django-oauth-toolkit#746

Thanks for finding that.

@ryanpetrello
Copy link
Contributor

I'm able to reproduce this:

In my testing, OAuth2 refresh tokens do not respect the expiration specified in REFRESH_TOKEN_EXPIRE_SECONDS:

curl -sk "https://ryan:[email protected]/api/v2/settings/authentication/" | jq '.OAUTH2_PROVIDER'
{
  "ACCESS_TOKEN_EXPIRE_SECONDS": 15,
  "AUTHORIZATION_CODE_EXPIRE_SECONDS": 600,
  "REFRESH_TOKEN_EXPIRE_SECONDS": 15
}
~ awx login --conf.username ryan --conf.password ryan --conf.client_id VQr23xzaE8qrrz7doFj3N8gAHEJR3pusVGFk40wl --conf.client_secret 9id8NqJXMjRpGMeBYCFVONB1218vpnS4jIbXLrImzXwH6aUPKR5NsmMiRlWSY7NzhAW4kx422eHdVRb5qppLdtcIPGjMLU25b2aX3IQF98U82IWwQkMiThJ6z6w0Hlru
{
     "token": "R1gWIQ4z9vYqgso2Yn8ZL1NwwU0EMt",
     "refresh_token": "ioDQ4gSXSu9l99HkoN4IFXDPsVecOE"
}
~ export TOWER_TOKEN=fvejfRrieTi6ESkodxJvQ74LpSYS7w
~ awx me | jq '.results[] | .username'
"ryan"

(wait 30 seconds or so for the token to expire)

~ awx me | jq '.results[] | .username'

Valid credentials were not provided.
$ awx login --help

Despite having a short-lived refresh token expiry, the refresh token allows you to create new access tokens after 15 seconds.

~ curl -k "https://VQr23xzaE8qrrz7doFj3N8gAHEJR3pusVGFk40wl:9id8NqJXMjRpGMeBYCFVONB1218vpnS4jIbXLrImzXwH6aUPKR5NsmMiRlWSY7NzhAW4kx422eHdVRb5qppLdtcIPGjMLU25b2aX3IQF98U82IWwQkMiThJ6z6w0Hlru@awx.example.org/api/o/token/" -X POST -d 'grant_type=refresh_token&refresh_token=u5N30sMCkBxkes2tSwpIVWyqp3BLZK'
{"access_token": "X3QghL09rBrNBUMq8yA9Ev85qy6Fnz", "expires_in": 15, "token_type": "Bearer", "scope": "write", "refresh_token": "yDYmhOE7swu5Ze3VnTU6IGXzb73CvX"}

@ryanpetrello
Copy link
Contributor

@sdwru,

Are you willing to give this PR a whirl?

#6631

@sdwru
Copy link
Author

sdwru commented Apr 7, 2020

@sdwru,

Are you willing to give this PR a whirl?

#6631

Yes, this appears to fix it for me. After the expiry time the response is The refresh token has expired. and the HTTP error code is 403 Forbidden

@ryanpetrello
Copy link
Contributor

Thanks @sdwru - this change will got out in the next release of AWX.

@squidboylan
Copy link
Contributor

I have verified this works on devel using the instructions provided in the issue.

@ryanpetrello
Copy link
Contributor

ryanpetrello commented Apr 15, 2020

@sdwru would you like to be acknowledged (in a CVE) for discovering and reporting this? If so, please reach out to me with the name you'd like to use for attribution (or post it here, if you're comfortable with that).

rpetrell<at>redhat.com

@sdwru
Copy link
Author

sdwru commented Apr 15, 2020

@sdwru would you like to be acknowledged (in a CVE) for discovering and reporting this? If so, please reach out to me with the name you'd like to use for attribution (or post it here, if you're comfortable with that).

rpetrell<at>redhat.com

You can just use @sdwru

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants