Hello again, Welcome to the second part of the blog series "OAuth Vulnerabilities." Here we will see the common vulnerabilities in OAuth. Read OAuth Vulnerabilites part 1.
The OAuth client must protect a few things. An organization must ensure that client secrets are in a safe place that others cannot access.
CSRF attack against the client
An attacker uses CSRF to execute an unwanted action on a user's browser by requesting a website where the user is logged in. With the help of an example attack, we will demonstrate this attack. Using a state parameter to prevent CSRF is highly recommended.
To better secure systems, consider using an OAuth client that supports authorization codes. When an OAuth callback endpoint receives a code parameter, the client trades it for an access token. The client passes the access token to the resource server when calling an API on behalf of the resource owner. Attackers can start an OAuth flow and obtain an authorization code from the target authorization server, stopping their "OAuth flow." A malicious attacker exploits a victim's client by consuming the attacker's authorization code. Attackers accomplish this by creating a malicious website.
On his website, something like:
To mitigate this, OAuth clients pass unguessable state parameters to authorization servers. An authorization server must return this value to the redirect URI as a parameter. Whenever the redirect URI is called, the client checks the state parameter. If the value passed initially does not match or is absent, a client terminates the flow with an error. This prevents attackers from injecting authorization codes into a victim's computer without their knowledge.
By attaching your social media profile, you can log in to the following test website via OAuth instead of using your username and password. An attacker can manipulate the OAuth flow to gain access to other users' accounts because of the client application's insecure implementation of the OAuth flow.
Once we click "Attach a social account," it will link the social media account to the profile.
An attacker will log in with the credentials and capture the request linking the account. The request will contain the OAuth code.
Once the code generates, the attacker will drop the request, which is required not to attach the account to the profile. An attacker will create a simple HTML file with the above IMG tag and host the file on the server.
Once visited by the victim, it will get attached to the victim's account.
Other things you can check include:
- Entropy verification
- Reuse of check state isn't allowed
- Make sure the request is invalid by removing the state and URI
OAuth account hijacking via redirect_uri
In addition to targeting the access token, this attack targets the authorization code. An attacker can steal a valid code or token to access the victim's data. A compromised account can lead to the attacker being able to access all applications registered with this OAuth service as the victim. To understand this attack, you should understand how browsers handle the URI fragment after the # in HTTP redirect responses (HTTP 301/302 responses).
The following test website allows users to log in with their social media accounts. A misconfiguration by the OAuth provider makes it possible for an attacker to steal authorization codes associated with other users' accounts.
Redirecting users to their original location after login is a common scenario on a website. If the user does not log in when they visit their app at "https://cobalt.io/app," the application redirects them to the login page. Once the user has logged in, the app will redirect them to https://cobalt.io/app.
After authorization, sensitive data, like an access token, is appended to the URL using the "redirect_uri." Consider a case where the redirect_uri can redirect to an attacker's server. When that happens, an attacker can access the victim's data using the access token.
After starting the OAuth flow, you can change the "redirect_uri" value to the attacker control website.
You will redirect to the attacker's control website (evil.com). This code will allow the attacker to complete the OAuth flow and control the victim's account.
In cases where the redirect URI accepts external URLs, such as accounts.google.com, use a redirector to get to any site you want: https://accounts.google.com/signout/chrome/landing?continue=https://appengine.google.com/_ah/logout?continue%3Dhttp://attacker:1337
There are lots of regular bypasses you can use
Weak Authorization Codes
Authentication bypass via implicit flow
To solve this problem, you can send this information as a POST request to the server and assign a session cookie to the user.
A simple change in the parameters sent to the server can allow an attacker to impersonate any user. As part of the implicit flow, attackers access this POST request through their browsers. This behavior can lead to a severe security vulnerability if the client application fails to ensure that the access token matches the rest of the request data.
The following test website allows users to log in with their social media accounts. An attacker can log into an account without knowing the password of another user due to inadequate validation by the client application.
By starting the OAuth flow, notice that the client application (the blog website) receives some basic information about the user from the OAuth service.
Upon receiving this information, it sends a POST request, and the access token to its own /authenticates endpoint.
By changing the email address to the victim's account, an attacker can log in to the victim's account using the attacker's access token.
An attacker is now logged in to the victim's account.
SSRF via OpenID dynamic client registration
OpenID Connect 1.0 is a simple identity layer on the OAuth 2.0 protocol. While OAuth 2.0 is about resource access and sharing, OIDC is about user authentication. It allows Clients to verify the identity of the End-User based on the authentication performed by an Authorization Server, as well as to obtain basic profile information about the End-User in an interoperable and REST-like manner.
The OpenID specification outlines a standardized way of allowing client applications to register with the OpenID provider. If dynamic client registration is supported, the client application can register by sending a POST request to a dedicated /registration endpoint.
An OAuth registration endpoint is available on the following test website, allowing dynamic registration via client applications. There's a potential vector for SSRF due to the OAuth service's unsafe use of client-specific data.
After the Initial recon, we can find the configuration file that can give us the endpoint for the registration.
You can create a suitable POST request to register your client application with the OAuth service. You must provide a redirect_uris array containing an arbitrary whitelist of callback URIs for your fake application.
We know from the OpenID specification that client applications can provide the URL for their logo using the logo_uri property during dynamic registration. This client id can fetch the logo for the specific client.
Go back to the POST /reg request in Repeater and replace the current logo_uri value with the target URL:
"logo_uri" : "http://169.254.169.254/latest/meta-data/iam/security-credentials/admin/"
Now visit the logo for the client ID mentioned in response to get the access token from the AWS manager.
Invalidate authorization code after use.
When used authorization codes are invalidated, attackers have to use captured or guessed authorization codes within a specific timeframe.
Intercept the request sent by the OAuth 2.0 client to the OAuth 2.0 Authorization Endpoint by configuring BurpSuite.
Please send it to BurpSuite Repeater. Try that request again in the Repeater and see if it works.
As part of OAuth, you may include the authorization code, the code challenge, and the code verifier in your URL. If the response_mode isn't set to form_post, the implicit flow sends the authorization token with the URL. The referrer header, log files, and proxy may leak the requested token or code. It's because these parameters are either passed in the query or fragment.
You can test this scenario by intercepting OAuth traffic with an HTTP interceptor like Burpsuite.
1. Check the URL for credentials and proceed with the authorization process.
2. Analyze the requests made to any external resources included in an OAuth flow. The referrer header could leak credentials.
One of the critical issues with OAuth is the general need for built-in security features. The security relies almost entirely on developers using the correct configuration options and implementing additional security measures, such as robust input validation.
It is important to note that vulnerabilities can arise in the client application and the OAuth service.
- redirect_uri validation: Only allow complete and exact matches rather than pattern matching. This prevents attackers from accessing other pages on the allowed domains.
- Enforce state parameter: Unguessable, random value can help protect users against CSRF-like attacks.
- access_token and client_id validation: verify that the access token was issued to the same client_id making the request.
- Scope validation: Check the requested scope to ensure that this matches the scope for which the token was initially granted.
- state parameter: Use it even though it is not mandatory.
- client_secret alternative: If the mobile or native desktop OAuth client applications are developed, use the PKCE (RFC7638) mechanism to provide additional protection against access code interception or leakage.
- Send a redirect_uri parameter not only to the /authorization endpoint but also to the /token endpoint.
- If you use the OpenID Connect id_token, ensure it is correctly validated according to the JSON Web Signature, JSON Web Encryption, and OpenID specifications.