Share this article:
Hey there! A few days ago, while doing penetration testing on one of the assets of our client, our team came through a scenario that is worth sharing. It was an OAuth based CSRF that help attacker to connect his Facebook account to that of victim causing Account Takeover. Curious about how it unfolded? Let’s dive into it.
OAuth is a way to let one app access certain parts of your account on another app without needing to share your password. For example, if you want to let a photo-editing app use your Instagram photos, OAuth lets you approve this access securely. Instead of giving the photo-editing app your Instagram password, OAuth provides a special key (called an access token) that lets the photo-editing app view and use your photos without ever seeing your password.
OAuth is a popular authorization framework designed with three primary roles in mind. The Client Application is the website or app seeking to access your data. The Resource Owner is the individual who owns this data and ultimately decides who can access it. Finally, the OAuth Service Provider is the entity that holds your data and manages access. This provider not only stores your data but also offers the tools, typically in the form of APIs, necessary for handling authorization requests and allowing data access.
OAuth can be implemented through various approaches known as grant types, with the two most significant being the implicit grant type and the authorization code grant type. Both of these grant types generally follow a similar process. Initially, the client application requests access to specific data, specifying the grant type it will use and the type of access it requires. Then, the user logs into the OAuth service, where they are prompted to give explicit consent for the requested access. Once the user consents, the client application receives a unique access token that confirms it has permission to access the data. The method of obtaining this token can vary depending on the grant type being used. With this access token, the client application can then make API requests to the resource server and retrieve the necessary data, completing the OAuth flow.
With an understanding of how OAuth operates, let’s examine the Proof of Concept (PoC) demonstrating how our team executed an Account Takeover via an OAuth-based CSRF vulnerability.
To begin, we logged into the site using our first account, which served as the attacker’s email. Upon login, an interface similar to the following appeared:
This Login Accounts option caught our attention and upon clicking it, we were able to see the following details:
The option to connect a Facebook account immediately drew our attention, so we decided to test this functionality. Next, we opened a different browser and logged into a second account. Upon doing so, an interface similar to the following appeared:
Here, upon seeing the connected accounts after clicking “Login Accounts”, none of the accounts were connected.
Now we moved to browser 1 where we had already opened the “Login Accounts” section and clicked on “Connect” button as highlighted below:
Upon clicking this button, we were redirected to Facebook’s login page where after entering the credentials, following page was displayed.
With this understanding of OAuth, let’s clarify the roles in this scenario: Facebook serves as the OAuth Service Provider, we are the Resource Owner (since our resources are being accessed), and the vulnerable site acts as the Client Application.
Returning to the PoC, once we clicked the “Continue as” button, we began intercepting requests. The first step involved Facebook issuing a unique access token, confirming that the vulnerable application had permission to access the data. Following this, the client application used this access token to make a request to Facebook, retrieving the necessary data. The intercepted request appeared as follows:
In the request above, state parameter acts as the CSRF token but the problem is this state parameter was same for all accounts and was not getting generated dynamically and was same for all accounts. We decoded its value and its value was like following:
{“wt”:”134″,”app”:”login”,”connect”:true,”next”:”https:\/\/redacted.com”}
We simply right clicked on the request and clicked on “Copy URL” button as highlighted below:
In the second browser, where we were logged in as the victim, we opened a new tab, pasted the copied link, and hit the Enter button. Bingo! our Facebook account was successfully linked to the victim’s account, as illustrated below:
After logging out of our attacker account in the first browser, we returned to the login page and clicked on the “Sign In with Facebook” button, as highlighted below:
We were redirected to Facebook’s login page where we entered our credentials and bingo! We have successfully logged in to victim’s account.
Tip: Whenever you’re testing for OAuth based CSRF, always check whether state parameter is correctly implemented or not. Presence of state parameter doesn’t mean that the site is secure from CSRF.
In conclusion, the exploration of OAuth vulnerabilities, particularly through the lens of Account Takeover via OAuth-based CSRF, highlights the critical importance of security in our digital interactions. As we continue to integrate various platforms and services, understanding the mechanisms behind these vulnerabilities becomes paramount for both developers and users. While this PoC sheds light on a specific exploit, it serves as a reminder of the broader implications of security practices in application development. Given the evolving nature of security threats, what measures do you believe are essential to safeguard our accounts and data? Do let us know your thoughts in the comments!
Get the latest updates and news by subscribing to our newsletter.
By subscribing, you agree to our Privacy Policy and consent to receive updates from our company.
Get the latest updates and news by subscribing to our newsletter.
By subscribing, you agree to our Privacy Policy and consent to receive updates from our company.