OAuth2 itself is fundamentally complicated as it is designed to resolve the vital authentication part in many complex web environments (mobile app, web server, etc). Due to the complexity, many security engineers may not fully understand the power of OAuth2. As a consequence, we are observing many security issues caused by a misconfiguration or poor implementation of OAuth2. To make it worse, some exploitations against these OAuth2 misconfigurations are extremely simple and easy to launch.
Let’s take a look at some common attack vectors or vulnerabilities against OAuth2 by referring to HackerOne public disclosure reports. We hope the explanations of these vulnerabilities are clear by making reference to the actual exploitation disclosure. At the end of each of the following sections, you will also learn how to mitigate these vulnerabilities.
https://hackerone.com/reports/665651
https://hackerone.com/reports/405100
The redirect_uri parameter in the OAuth2 workflow is used by the authorization server as a location or address to deliver the access_token or auth_code by means of a browser redirect. In Figure 1, we described that the redirect_uri parameter is initialized by the client application as part of the request to the authorization server under step 2 when a web user clicks the login button. After the authorization server validates the credentials (step 6), it will send back the auth_token (or access_token for an implicit grant step 7 in Figure 2) as a parameter to the redirect_uri used in step 2.
If a malicious user could trigger the victim to send a request to the authorization server with a redirect_uri controlled by the attacker and the authorization server is NOT validating the redirect_uri, the access_token will be sent to the URI controlled by the attacker.
The case of stealing users’ OAuth tokens via redirect_uri is, unfortunately, a typical one, where the authorization server performs a poor validation on the redirect_uri and the attacker is able to bypass the validation with a malicious link they control.
Implement a robust redirect_uri validation on the authorization server by considering the following approach:
https://hackerone.com/reports/111218
https://hackerone.com/reports/13555
In OAuth2 implementation, the state parameter (initialized under step 2) allows client applications to restore the previous state of the user. The state parameter preserves some state object set by the client in the authorization request and makes it available to the client in the response.
Here is the correct implementation of the state parameter:
However, since the state parameter is not required for a successful OAuth2 workflow, it is very often this parameter is omitted or ignored during OAuth2 implementation. Without validation on the state parameter, CSRF attack could be launched easily against the client application.
This HackerOne report is a very good example to explain how an attacker could attach their account to a different account under the client application due to the lack of the state parameter. Sometimes, even the state parameter is present in the callback request from the authorization server, but it is still possible the state parameter is not validated, leaving the application vulnerable to CSRF attack.
Ensure the state parameter is passed between requests and state validation is implemented so that an attacker could not attach their account to the victim’s account.
https://hackerone.com/reports/272824
https://hackerone.com/reports/397527
The client_secret is used by the client application to make a request to the authorization server to exchange the auth code to the access token (step 8 in Figure 1). The client_secret is a secret known only to the client application and the authorization server.
Some developers may accidentally disclose the client_secret to end users because the access_token retrieve request (step 8 in Figure 1) is mistakenly executed by some front-end JavaScript code rather than performed by the back-end channel.
In reference to this HackerOne Report about token disclosure, the client_secret is publicly exposed in the HTML page as the exchanging auth_code with access_token (Step 8 in Figure 1) process is executed by a piece of JavaScript code.
To avoid disclosing client_secret to the public, it is best for developers to understand the need of implementing OAuth2, as there are different OAuth2 options to adopt for different applications. If your client application has a back-end server, the client_secret should never be exposed to the public, as the interaction with the authorization server could be completed in a back-end channel. If your client application is a single-page web application or mobile app, you should choose a different OAuth2 type. For example, use the Authorization Code grant with PKCE instead.
https://hackerone.com/reports/1074047
A pre-account takeover could occur when the following two conditions are met:
This HackerOne report details how a misconfigured OAuth can lead to pre-account takeover:
Perform email validation when creating a new user.
https://hackerone.com/reports/835437
https://hackerone.com/reports/787160
https://hackerone.com/reports/202781
One weak design of OAuth2 itself is that it passes the access_token in the URL for implicit grant type. Once you put sensitive data in a URI, you risk exposing this data to third-party applications. This applies to OAuth2 implementation as well.
In this HackerOne report about access_token smuggling, for example, the access_token was exposed to a third-party website controlled by the attacker after a chained redirection by taking advantage of the referrer header.
As this is a design issue of OAuth2, the easiest mitigation method would be strengthening the referrer header policy with <meta name="referrer" content="origin" />.
https://hackerone.com/reports/245408
A lack of access_token validation by the client application makes it possible for an attacker to log in to other users' accounts without knowing their password.
Once the authorization server sends the access_token back to the client application, client applications sometimes need to bind the access_token with a user identity so that it can store it as a session. The exploitation of this vulnerability happens when an attacker binds their access_token with any user identity and then impersonates that user without logging in.
In this HackerOne report, the security researcher was able to log in as any user just by supplying the victim’s email address only because the client application did not validate whether the access_token belongs to the correct owner.
Validation should be performed on the client side to check whether the user owns the access_token.
The OAuth2 framework is complicated and provides many flexibilities for implementation. However, due to this flexibility, the security of OAuth2 implementation is in the hands of the developers. With that said, developers with a strong security mindset can make implementation more secure; on the contrary, developers with less security training are likely to impose some security holes during OAuth2 implementation. For any organization, it’s vital to train and educate your developers with the latest security best practices to reduce risk during OAuth2 implementation.
At Coupa, our engineers are committed to following the latest OAuth2 security best practices to make sure our OAuth2 implementation is secure.
Coupa Software Inc. All Rights Reserved