Siunam's Website

My personal website

Home About Blog Writeups Projects E-Portfolio

Authentication bypass via OAuth implicit flow | Jan 3, 2023

Introduction

Welcome to my another writeup! In this Portswigger Labs lab, you’ll learn: Authentication bypass via OAuth implicit flow! Without further ado, let’s dive in.

Background

This lab uses an OAuth service to allow users to log in with their social media account. Flawed validation by the client application makes it possible for an attacker to log in to other users’ accounts without knowing their password.

To solve the lab, log in to Carlos’s account. His email address is carlos@carlos-montoya.net.

You can log in with your own social media account using the following credentials: wiener:peter.

Reconnaissance

Home page:

In here, we can go to the “My account” link to login.

Let’s click that and intercept the requests via Burp Suite:

When we clicked that link, we’ll be redirected to /social-login:

Then, it’ll send a GET request to /auth, with parameter client_id, redirect_uri, response_type, nonce, and scope. Which indicates that it’s using OAuth.

Authorization code grant type:

Now, we’ve send a request to the OAuth service’s /auth endpoint asking for permission to access specific user data.

This request contains the following noteworthy parameters, usually provided in the query string:

Armed with above information, we now know that our response_type is set to token which is the implicit grant type.

Implicit grant type:

Now, let’s forward the authorization request.

When the authorization server receives the initial request, it will redirect the user to a login page, where they will be prompted to log in to their account with the OAuth provider.

Let’s login with our own social media account:

In here, this is based on the scopes defined in the authorization request. The user can choose whether or not to consent to this access.

Let’s click “Continue”, to consent to this access.

If the user gives their consent to the requested access, the OAuth service will redirect the user’s browser to the redirect_uri specified in the authorization request. Then, the authorization code will send the access token and other token-specific data as a URL fragment. E.g: /oauth-callback#access_token=6WCCPFA1jHBaL0Qc7RnLhmK8Zv0J8ghNUB3Vaj6V3VW&expires_in=3600&token_type=Bearer&scope=openid%20profile%20email.

Once the client application has successfully extracted the access token from the URL fragment, it can use it to make API calls to the OAuth service’s /me endpoint:

Burp Suite’s HTTP History:

The resource server should verify that the token is valid and that it belongs to the current client application. If so, it will respond by sending the requested resource i.e. the user’s data based on the scope associated with the access token:

The client application can finally use this data for its intended purpose. In the case of OAuth authentication, it will typically be used as an ID to grant the user an authenticated session, effectively logging them in:

Exploitation

Now we knew this lab’s OAuth is implemented the implicit grant type, which is mainly recommended for single-page applications.

In this flow, the access token is sent from the OAuth service to the client application via the user’s browser as a URL fragment. The client application then accesses the token using JavaScript. The trouble is, if the application wants to maintain the session after the user closes the page, it needs to store the current user data (normally a user ID and the access token) somewhere.

To solve this problem, the client application will often submit this data to the server in a POST request and then assign the user a session cookie, effectively logging them in. This request is roughly equivalent to the form submission request that might be sent as part of a classic, password-based login. However, in this scenario, the server does not have any secrets or passwords to compare with the submitted data, which means that it is implicitly trusted.

In the implicit flow, this POST request is exposed to attackers via their browser. As a result, this behavior can lead to a serious vulnerability if the client application doesn’t properly check that the access token matches the other data in the request. In this case, an attacker can simply change the parameters sent to the server to impersonate any user:

Let’s log out our account, then log back in, and change the POST /authenticate request’s email parameter value to carlos@carlos-montoya.net:

Note: The first time the user selects “Log in with social media”, they will need to manually log in and give their consent, but if they revisit the client application later, they will often be able to log back in with a single click.

Change email parameter value to carlos@carlos-montoya.net:

Then forward the request.

I’m user carlos!

What we’ve learned:

  1. Authentication bypass via OAuth implicit flow