DNS rebinding
TL;DR: Attacker domain TTL=0 flips between attacker IP (load script) and victim internal IP (same-origin requests). Bypasses SOP at the IP layer.
What it is
Same-origin policy is keyed on (scheme, host, port) — the hostname, not the resolved IP. An attacker who controls authoritative DNS for evil.tld can return their own IP first (to deliver JS), wait for the browser to time-out the cache, then return an internal/RFC1918 IP for the same hostname. The page’s own scripts now talk to the internal target as same-origin, defeating SOP-based isolation that internal services rely on.
Preconditions / where it applies
- Victim browses to attacker domain (phishing, malvertising)
- Target service reachable from victim’s network (router admin, dev server, internal API, IoT, metadata endpoints)
- Target accepts requests with arbitrary
Host:header (no virtual-host enforcement) - DNS cache TTL ≤ a few seconds, or browser uses short pinning windows
Technique
- Stand up authoritative DNS (e.g.
whonow, custom Pythondnslib) that returns differing answers per-query: first query → attacker IP, subsequent →192.168.1.1/169.254.169.254/127.0.0.1. - Victim loads
http://rebind.evil.tld/→ resolves to attacker IP, gets attacker JS. - JS keeps an XHR loop running:
1 2 3 4
async function poke(){ try { const r = await fetch('/admin/info'); return await r.text(); } catch(e){ setTimeout(poke, 1500); } }
- After browser pin expires, the second DNS lookup returns the internal IP. The XHR now hits
192.168.1.1but the browser thinks it is same-origin withrebind.evil.tld, so the response body is readable. - JS reads and exfiltrates router config / credentials / cloud metadata to attacker collector.
- Singularity-of-origin (NCC Group) automates multi-target attacks, port scanning, and payload selection.
- Variants: multi-A record (return both attacker and target IPs, attacker IP firewalled to force fallback), WebRTC IP discovery to learn victim’s LAN range first.
Detection and defence
- Services: enforce
Host:header allowlist (only acceptHost: 192.168.1.1or known hostname); reject unknown. - Require authentication on every endpoint, even on localhost / LAN — no “trusted network”.
- TLS everywhere internally; rebinding cannot match cert SAN.
- Browsers pin DNS for the page lifetime against private-IP rebinds (Chrome
--enable-features=PrivateNetworkAccessRespectPreflightResults); enable PNA preflights. - Block RFC1918 / link-local / loopback responses for public-suffix domains at the resolver (dnsmasq
--stop-dns-rebind, Unboundprivate-address). - Cloud metadata: require
Metadata: true(Azure) or IMDSv2 token (AWS) — defeats simple rebind because the token request needs PUT/header that fetch from a foreign origin cannot provide without preflight. - Related: ssrf, ssrf-to-cloud, cors-misconfig.
References
- NCC Group — Singularity of Origin — automated rebind framework
- whonow — minimal rebinding DNS server
- Chromium — Private Network Access — browser mitigation