Stealing OAuth access tokens via an Open Redirect
Challenge can be found: https://portswigger.net/web-security/oauth/lab-oauth-stealing-oauth-access-tokens-via-an-open-redirect
Preface
Compared to the OAuth Account Hijacking via redirect_uri challenge, in this case the Authorization Server seems to verify the redirect_url
correctly except allowing additional information to be appended to the path. While in the majority of cases this would not necessarily lead to a vulnerability right away, it can lead to theft of an OAuth Access Token if the underlying web application is vulnerable to Open Redirect.
Reproduction Steps
As mentioned in the preface, in order for this vulnerability to work, the web application will need to be susceptible to a vulnerability such as Open Redirect. In this case, an Open Redirect was discovered in the post/next
route:
Response:
Before moving further, validation of how the Authorization Server treats the redirect_uri
is required. This means does the Authorization Server use a fuzzy match such as verifying that the host is correct? Or whether a strict verification meaning it strictly validates a one-to-one match with the URL.
It's simple to verify this, start the OAuth flow and note the redirect_uri
which is passed by the Client to the Authorization Server:
Replay the respective request and modify the redirect_uri
and observe whether the response is the same as before:
The response is clearly not the same and the server throws the following error:
You can go through the process of verifying whether maybe it only checks if the domain is in the URL, etc. However for the sake of brevity purposes, in this case the Authorization Server verifies the whole URL even down to the path. Although one interesting thing is that anything can be appended to the path and the logic will still return true:
With this in mind, the Open Redirect vulnerability can now be chained with this feature to use dot dot slash ../
in order to traverse to the endpoint vulnerable to Open Redirect:
To test whether this works, proceed with the OAuth flow as normal however intercept the request which contains the redirect_uri
and modify it to the value shown above.
After finishing with the OAuth dance, notice that the browser is redirected to:
As shown in the URL above, the access_token
is appended as a URL fragment as the Implicit Flow is in-use.
In case you are curious, the URL fragment being persisted in a redirect is an interesting topic and is solely based on how the client (aka browser) handles it. RFC7231 mentions that the browser should inherit the URL fragment and append it for a subsequent redirect:
Furthermore, it also states that it's the server's responsibility to clear out the fragment in the case where it may contain sensitive information:
Last updated