# OAuth `redirect_uri` bypass using IDN homograph attack resulting in user's access token leakage

Semrush OAuth redirect_uri validation accepted IDN homograph domains like oauth.šemrush.com, leaking authorization codes to attacker-registered punycode domains.

- Payout: hidden
- Severity: medium
- Program: Semrush
- Found by: yassineaboukir
- Disclosed: 2020-06-18
- Write-up quality: 7/10
- Original: https://hackerone.com/reports/861940
- Library page: https://bugbountylibrary.com/r/h1%3A861940
- Tags: area:web domain:web impact:ato impact:data-leak kind:bounty platform:hackerone sev:medium tech:oauth technique:unicode-normalization vuln:auth-bypass vuln:open-redirect

**Target:** OAuth2 authorize endpoint (oauth.semrush.com)
**Root cause:** The OAuth server validated redirect_uri against semrush.com without normalizing IDN/punycode, so visually identical Cyrillic-character domains were treated as belonging to semrush.com.
**Steps:**
1. Register the punycode domain `xn--emrush-9jb.com` (corresponds to `šemrush.com`).
2. Send victim the authorize URL with `redirect_uri=https://oauth.šemrush.com/oauth2/success` and `client_id=seoquake`.
3. Victim approves; browser resolves the IDN to punycode and sends the OAuth code to the attacker's domain.
4. Attacker exchanges the leaked code for the victim's access token.
**How found:** Noticed the OAuth redirect_uri validation appeared to compare hostnames without IDN normalization, hypothesized that Unicode lookalike characters (Cyrillic е) would be mapped to semrush.com, and tested with a homograph subdomain.
**Exploitation:** Attacker registers the punycode equivalent of a homograph domain, crafts an authorize link with the homograph redirect_uri, and after victim consent receives the OAuth authorization code on their server, then exchanges it for tokens granting access to the victim's account data.
**Insight:** When testing OAuth redirect_uri allowlists, try IDN homograph variants of the trusted domain (Cyrillic/Greek lookalikes) and their punycode forms; backends that string-match or loosely normalize may accept them while browsers resolve to attacker-registered punycode domains.

