OAuth Attacks
OAuth is a standard designed to enable secure authorization between services and applications. It is widely used in Single Sign-On (SSO) scenarios, where a user can authenticate once and access multiple applications without sharing their credentials with each service.
OAuth Basic Overview
OAuth Entities
The OAuth protocol defines the following entities:
Resource Owner - Typically the user who owns the protected resources.
Client - The application requesting access to the resources on behalf of the user.
Authorization Server - The server responsible for authenticating the user and issuing access tokens.
Resource Server - The server hosting the protected resources. It can be the same as the authorization server, or a separate one.
OAuth Standard Communication Flow
The communication flow between the previous entities works as follows:
The client requests authorization from the user.
The user consents to giving access to their profile to the third-party service, granting authorization.
The client presents the authorization grant to the authorization server.
The client receives an access token from the authorization server
The client presents the access token to the resource server
The client receives the resource from the resource server
Authorization Code Grant
The authorization code grant is the most common and secure OAuth flow. It strictly follows the standard OAuth process and ensures that sensitive tokens are exchanged server-to-server rather than through the userβs browser.
Implicit Code Grant
The implicit grant is a simplified OAuth flow intended for clients that cannot securely store a client secret (typically browser-based JavaScript applications). This grant type is less secure because the access token is sent from the OAuth service to the client application via the user's browser as a URL fragment.
Identifying OAuth authentication
To identify whether an application uses OAuth, look for options to log in with an external account.
All OAuth flows begin with a request to the /authorization endpoint, which includes parameters like client_id, redirect_uri, and response_type.
response_type can either be code to use standard authorization or token to use the (insecure) implicit grant authorization flow
If a third-party OAuth provider is involved, its hostname in the authorization request usually reveals which service is being used, and its public documentation can expose details about endpoints and configuration.
After identifying the authorization serverβs hostname, it is useful to probe the standard discovery URLs:
/.well-known/oauth-authorization-server/.well-known/openid-configuration
These often return JSON configuration files that reveal supported features, additional endpoints, and other information that can expose a broader attack surface than what is documented.
Stealing Access Tokens
This vulnerability occurs when the redirect_uri is not properly verified by the authorization server.
An attacker can steal a victim's access token by manipulating the redirect_uri parameter to make redirect the user to a server they own. In particular:
The attacker needs to create a link for an
authorization requestthat contains a manipulatedredirect_uriand set thestateparameter to an arbitrary value as long as it is always the same for the entire attack.The request's
client_idparameter can be extracted by executing the OAuth flow with the attacker's credentials and re-using the client_id.After receiving the manipulated link, the user logs in and gets redirected to the attacker's server, sending them a request with the login parameters.
The attacker's server will show a request specifying the authorization code for the user's account
The attacker can now complete the OAuth flow and exchange the authorization token for a valid access token, thereby impersonating the victim. The attacker can easily achieve this by forging the access token request, since all required parameters are known:
/client/callback?code=<stolen-code>&state=<state>The remaining OAuth flow is completed by the client and authorization server in the background. The victim's access token is returned in the response. Since the attacker now owns a valid access token for the victim, they can use it to impersonate the victim
In real-world applications, the redirect_uri parameter is usually filtered. You can sometimes find misconfigured whitelists allowing any value that contains the hostname. Considering you are attacking example.com and own attacker.server, you can bypass the filters using redirect values such as:
A misconfigured redirect_uri parameter can also cause SSRFs and Open Redirects!
CSRF via missing state parameter
The state parameter in the OAuth flow is an optional parameter that serves as an anti-CSRF measure.
A missing (or improperly validated) state parameter easily leads to a CSRF vulnerability
Whenever an OAuth implementation lacks the state parameter in the authorization request, it is possible to perform a CSRF attack to cause the victim to be logged in as the attacker's account.
While this may not seem like a useful attack, it might be a strong vector in some applications where the user might add personal data or credit card data to the attacker's account.
To execute the CSRF attack on an OAuth flow without a state parameter:
Get a valid authorization code your account by sending an authorization request and authenticating to the application.
Check the response to obtain the authorization code tied to your account and craft the callback link:
http://example.com/client/callback?code=<your-code>Just like in a regular CSRF attack, the link will need to a user via other methods.
When a user clicks the provided link, their browser will automatically complete the OAuth flow, making them log in with the attacker's account.
Reflected XSS
Sometimes, the authorization request:
reflects back some (or all) parameters as hidden values in the response.
In that case, considering the vulnerability exists in the authorization request, it can potentially result in a full account takeover of a victim's account.
