# Blacklist bypass on Callback URLs

DNS rebinding bypassed Coinbase's RFC6890 blacklist on callback URLs, letting the outbound proxy reach loopback services like 127.0.0.1:80/_hostmanager/healthcheck.

- Payout: $100
- Severity: medium
- Program: Coinbase
- Credited: agarri_fr
- Disclosed: 2016-09-14
- Write-up quality: 7/10
- Original: https://hackerone.com/reports/53004
- Library page: https://bugbountylibrary.com/r/h1%3A53004
- Tags: domain:web impact:internal-access kind:bounty platform:hackerone sev:medium tech:rest technique:chained vuln:ssrf

**Target:** Callback URL feature / outbound proxy (Proximo)
**Root cause:** The app resolves the callback hostname and checks the IP against a blacklist, but the outbound proxy re-resolves the hostname independently without the blacklist, so a rebinding DNS server returns a safe IP to the filter and a private IP to the proxy.
**Steps:**
1. Set up a custom DNS server (patched dnschef) with scheme 221: answer safe IP twice, then 127.0.0.1, then repeat
2. Run `./rebind.py --ip1=127.0.0.1 --ip2=92.243.29.213 --scheme=221`
3. Submit callback URL `http://test42.sqli.nicob.net/_hostmanager/healthcheck` in Merchant settings
4. App resolves hostname, sees 92.243.29.213, passes blacklist check
5. Proxy re-resolves, gets 127.0.0.1, fetches loopback service
6. Observe proxy's loopback index page / healthcheck response in web UI
**How found:** Recalled prior report #47368 where callbacks reached private IPs, noted aianus's comment that RFC6890 ranges were now blocked, and hypothesized the check and the proxy resolve separately — testable via DNS rebinding.
**Exploitation:** Attacker controls DNS for a hostname and alternates answers so the validation resolver sees a public IP while the Proximo outbound proxy resolves to 127.0.0.1, causing the proxy to fetch internal loopback services (ports 80, 1080, 8000, 9177) and reflect responses back through the callback UI.
**Escalation:** Port scanning of proxy loopback revealed multiple services (80, 1080, 8000, 9177); metadata server 169.254.169.254 was unreachable, limiting impact.
**Insight:** When a URL-fetch feature validates a hostname's resolved IP but hands the hostname (not the IP) to a downstream fetcher/proxy, the two resolutions can diverge — DNS rebinding defeats the check. Test by alternating DNS answers between a public IP and 127.0.0.1.
