OAuth Account Takeover via redirect_uri bypass

sso.hotmart.com — Hotmart
Critical
Affected Component
/oidc/authorize — Apereo CAS OIDC provider with prefix-only redirect_uri validation
Root Cause
The SSO validates redirect_uri by checking if it starts with https://app.hotmart.com. Any domain matching this prefix is accepted, including attacker-controlled domains like app.hotmart.com.evil.com. The token endpoint requires client_secret to be present but accepts any value.
Attack Vector
Victim clicks a crafted link → SSO redirects with authorization code to attacker domain → attacker exchanges code for tokens with arbitrary client_secret → full profile, email, address, internal IDs exfiltrated.
Discovery
Source map analysis of account-auth SPA revealed OIDC client_id and client_secret. Testing confirmed prefix-only redirect validation and unenforced secret.

Proof of Concept

A popup opens sso.hotmart.com/oidc/authorize with redirect_uri pointing to this server (app.hotmart.com.poc.0xd0m7.xyz), which passes the prefix validation.
If the victim has an active Hotmart session, the SSO issues an authorization code and redirects to our callback.
The callback page captures the code and sends it back via window.opener.postMessage().
This page exchanges the code for an access_token at /oidc/accessToken using client_secret=x (any value works), then fetches the victim's full OIDC profile.
One-click attack. If the victim is signed in to Hotmart, clicking the link grants the attacker a ~47-hour access token with full profile access. No interaction required beyond the initial click.
Victim Identity — Stolen via OAuth
Email
-
Name
-
Login
-
User ID
-
Authorities
-
Access Token (valid ~47h)
-
Account Takeover — Full Profile Exfiltrated
Email
-
User ID
-
Authorization Code
-
Captured via redirect_uri bypass
Token Expiry
-
Full API access during this window
OIDC Profile (userinfo)
Decoded id_token JWT claims
Replay stolen token (curl)