09. DNS Rebinding: The Boundary Between Origin and Endpoint
DNS Rebinding is an attack in which an attacker changes DNS answers for a hostname they control so that a browser first receives code from an external server and later connects through the same hostname to an internal-network or loopback service. The key is not hacking DNS itself, but exploiting the gap between a web origin's identity and its actual network endpoint.
It is often described as a "Same-Origin Policy (SOP) bypass," but the browser does not skip its SOP check. An origin in RFC 6454 is approximately a (scheme, host, port) tuple; the resolved IP address is not part of it. If those three URL components remain the same, the origin comparison remains the same even when DNS points to a different endpoint.
The exercise in this document is a static data model that performs no DNS lookup, socket connection, or browser request. Do not attempt internal-address discovery or service access outside an authorized local environment.
Threat model
The following conditions must all hold for the attack to work.
- The attacker controls a domain, its authoritative DNS answers, and the initial web content.
- The victim's browser continues executing active content received from the initial endpoint.
- Browser, operating-system, and proxy caches expire and connection reuse ends, causing the hostname to be resolved again for a new connection.
- A subsequent DNS answer points to a private, link-local, or loopback endpoint reachable from the victim's location.
- The target service responds over the same scheme and port and does not reject an unexpected
Host,Origin, or TLS identity. - Additional protections such as the browser's Local Network Access do not block the request.
A short TTL alone does not guarantee success. Browser and operating-system DNS caches, HTTP keep-alive, HTTP/2 connection coalescing, proxies, and multiple A or AAAA answers all affect when resolution actually occurs again. Memorizing one browser-specific "rebinding delay" as a general rule is therefore incorrect.
Attack flow
Consider the example URL http://lab.example.test:8080/.
1. lab.example.test -> 192.0.2.10
The browser receives the document and script from an external endpoint.
2. document origin = (http, lab.example.test, 8080)
The script executes with the authority of this origin.
3. On a new connection, lab.example.test -> 127.0.0.1
The URL and origin tuple remain unchanged, but the network endpoint changes.
4. request target = 127.0.0.1:8080
Host = lab.example.test:8080
If the target service accepts the request, the script still appears to be requesting its own origin. This is why ordinary cross-origin CORS checks are not the fundamental boundary when reading the response. An origin tuple alone cannot express that control of the endpoint behind a hostname changed.
A 2007 paper by Jackson et al. describes this as the confusion created by grouping network resources controlled by different principals under one origin. The attacker provides legitimate authoritative answers for its own domain, so DNS cache poisoning is unnecessary. The attacker can also correctly sign its own zone, meaning that DNSSEC alone does not prevent the attack.
Distinguishing similar problems
It is not a CORS misconfiguration
CORS is an opt-in mechanism that allows another origin to read a response. The two DNS Rebinding requests can be evaluated as same-origin because their hostname remains the same, so merely removing Access-Control-Allow-Origin does not restore the boundary.
By contrast, if an external origin can read an internal API response without DNS Rebinding, the CORS configuration may be the direct cause. Endpoints that can change state even when the response cannot be read also require separate CSRF defenses.
It is not DNS poisoning
DNS poisoning corrupts the resolution of a domain trusted by the victim. In DNS Rebinding, the attacker returns valid answers for its own domain, so taking over a resolver or cache is unnecessary.
The acting deputy differs from SSRF
In browser-based DNS Rebinding, the user's browser is the deputy that reaches into the internal network. In SSRF, a server-side URL fetcher is the deputy. Server-side systems can also have a rebinding or TOCTOU problem when DNS results differ between URL validation and connection time, but the connecting actor and defensive boundary are different.
Safe local model
The following code places an RFC 5737 documentation address and a loopback address in a static array to model a state in which the origin remains unchanged while only the endpoint changes. It uses no DNS, HTTP, JavaScript, or socket API and sends no packets to any host.
from dataclasses import dataclass
from urllib.parse import urlsplit
@dataclass(frozen=True)
class Origin:
scheme: str
host: str
port: int
def origin_of(url: str) -> Origin:
parsed = urlsplit(url)
if parsed.scheme not in {"http", "https"} or parsed.hostname is None:
raise ValueError("absolute HTTP(S) URL required")
default_port = 443 if parsed.scheme == "https" else 80
port = parsed.port if parsed.port is not None else default_port
return Origin(parsed.scheme, parsed.hostname, port)
url = "http://lab.example.test:8080/status"
document_origin = origin_of(url)
# Static learning data, not a real resolver.
resolved_endpoints = ("192.0.2.10", "127.0.0.1")
first_endpoint, rebound_endpoint = resolved_endpoints
assert origin_of(url) == document_origin
assert rebound_endpoint != first_endpoint
print(f"origin: {document_origin}")
print(f"first endpoint: {first_endpoint}:8080")
print(f"rebound endpoint: {rebound_endpoint}:8080")
print(f"origin changed: {origin_of(url) != document_origin}")
print(f"endpoint changed: {first_endpoint != rebound_endpoint}")
The output is:
origin: Origin(scheme='http', host='lab.example.test', port=8080)
first endpoint: 192.0.2.10:8080
rebound endpoint: 127.0.0.1:8080
origin changed: False
endpoint changed: True
This model proves only the identity mismatch, not the feasibility of a real attack. In practice, DNS caches, transport connections, browser policy, TLS, and service authentication are all additional variables.
What to verify in an authorized environment
In a lab using only a browser and two endpoints you own, record the following pieces of evidence separately.
- The initial document URL and origin tuple
- The remote address to which each request actually connected
- The timing of DNS queries and their A and AAAA answers
- Whether a connection was reused and when a new one was created
- The
Host,Origin, method, and authentication state received by the target service - If the browser blocked the request, the exact policy name recorded in the console
A short TTL or changed DNS answer does not prove a vulnerability. You need evidence that active content under the same origin actually reached a different endpoint and crossed the service's security boundary. Scanning production-network addresses or accessing third-party equipment is outside this verification scope.
Defense: do not mistake an internal network for authentication
Depending on one layer lets differences among browser, DNS, and network implementations break the defense. Start with the target service, then layer outward defenses in the browser and resolver.
1. The service validates its own identity
- Explicitly manage allowed
Hostvalues or HTTP/2 and HTTP/3:authorityvalues at both the reverse proxy and application, rejecting unknown values before routing. - Ensure the proxy does not unconditionally overwrite an external
Hostwith a trusted internal hostname. Later layers must preserve the value validated at the first ingress. - Use HTTPS where possible and accept only certificates valid for the target service's intended hostname. A TLS client connecting under an attacker hostname should fail certificate-identity validation, and users must not be encouraged to bypass the warning.
- Apply authentication and authorization to every sensitive function. A source IP, loopback address, or private-network reachability is not a credential.
- Verify that the request's
Originexactly matches a service-origin allowlist fixed in trusted configuration. Deriving the allowlist dynamically from the request'sHostcan let both checks be bypassed together. Some clients omitOrigin, so this check does not replace authentication. - Retain CSRF tokens, Fetch Metadata, and safe methods as separate protections against ordinary cross-site requests. A rebinding script may appear same-origin, send
Sec-Fetch-Site: same-origin, and read the token response, so do not count these mechanisms as direct DNS Rebinding defenses. - Do not expose sensitive administrative responses through unauthenticated
GETrequests.
Binding only to loopback reduces direct access from the LAN, but it is not a complete DNS Rebinding defense because the browser on the same host can also reach loopback. Host validation and authentication remain necessary.
2. Use the browser's local-network boundary as a supporting defense
Local Network Access (LNA) is a WICG browser proposal that requests user permission when a public context connects to a local or loopback endpoint and restricts the ability to request that permission to secure contexts. You therefore cannot infer from the earlier http://lab.example.test model that an actual browser will display a permission prompt. Mixed-content rules and implementation status may block the request before a prompt.
Chrome's 2025 announcement describes a point-in-time implementation snapshot: an opt-in test enabled by a flag in Chrome 138, support at the time for fetch, subresources, and subframes, and limitations involving WebSockets and other transports. It is not evidence that the same policy is deployed in every current Chrome release or other browser. Verify actual behavior by browser version and transport in the deployment matrix, and treat LNA as defense in depth above service authentication.
3. Filter rebinding at resolver and network boundaries
- Organizational resolvers should block answers where a public DNS name resolves to private, link-local, or loopback addresses.
- Design DNS-egress and encrypted-DNS policies together so clients cannot bypass the policy through an arbitrary external resolver.
- Apply the same decision to A and AAAA records, IPv4-mapped IPv6 addresses, and the entire CNAME chain.
- Handle intentional split-horizon DNS and public-to-private failover domains through a narrow, recorded allowlist.
This reduces routes around a firewall but does not replace service authentication. Alternative resolvers, VPNs, proxies, and attacker-controlled origins already inside the network may remain.
4. Pin the endpoint immediately before a server-side URL fetch
SSRF defenses must inspect more than a hostname string.
- Restrict allowed schemes, ports, and hostnames first.
- Normalize every A and AAAA result and reject private, loopback, link-local, multicast, and reserved ranges.
- Connect to the validated IP and prevent the HTTP client from resolving the hostname again in between.
- Validate the TLS certificate against the originally allowed hostname.
- Re-run URL and DNS validation from the beginning after every redirect.
Resolving "once more just before the request" while still allowing the client to resolve again leaves a race between check and use. Also distinguish this defense for a server-side deputy from the browser-based attack.
Defenses that commonly fail
- Disable only CORS — after rebinding, a request can still be same-origin when the URL hostname remains unchanged.
- Enable only DNSSEC — an attacker can legitimately sign changing answers in a zone they own.
- Ignore short TTLs and cache for a long time — this may reduce risk, but dynamic DNS, failover, and multiple network stacks prevent it from providing a standalone guarantee.
- Leave services inside the firewall unauthenticated — the browser already has a network vantage point inside the firewall.
- Block only
127.0.0.1— RFC 1918, link-local, IPv6 loopback and ULA, IPv4-mapped IPv6, and other local address spaces remain. - Check only
Host— it is an important defense, but does not solve trusted internal hostnames, proxy rewriting, or non-HTTP protocols.
Defense verification checklist
- Are unknown
Hostand:authorityvalues rejected at the first ingress? - Do internal and loopback services have independent authentication and authorization?
- Does the expected
Originallowlist come from trusted configuration rather than the request'sHost? - Are CSRF tokens and Fetch Metadata excluded from being counted as standalone DNS Rebinding defenses?
- Is the HTTPS certificate validated against the intended service hostname?
- Has browser-specific LNA behavior for public-to-local requests been tested for each actual transport?
- Does resolver filtering cover A, AAAA, CNAME, and IPv4-mapped IPv6 addresses?
- Does the server-side fetcher connect to the validated IP and revalidate every redirect?
- Do regression tests allow the expected hostname and reject an attacker-controlled hostname?
Related documents
- Complete SSRF Guide — server-side deputies and outbound URL validation
- Validating SSRF Quickly with OAST — recording DNS and HTTP evidence within an authorized scope
- CORS Misconfiguration and Practical Exploitation — cross-origin opt-in problems versus same-origin rebinding
- Quick Checks for Host Header Attacks — the hostname trust boundary between proxy and application
References
- RFC 6454 — The Web Origin Concept — standard definition of the origin tuple and its DNS dependency
- Jackson et al., “Protecting Browsers from DNS Rebinding Attacks” (CCS 2007) — systematic treatment of the attack model and browser, resolver, and server defenses
- RFC 9110 §7.2 — Host and :authority — rules for carrying HTTP target authority
- WICG Local Network Access — permission-based browser proposal for public-to-local and loopback requests
- Chrome, “A new permission prompt for Local Network Access” — Chrome's LNA rollout scope and known limitations
- RFC 5737 — IPv4 Address Blocks Reserved for Documentation — defines
192.0.2.10in the local model as documentation-only - RFC 2606 — Reserved Top Level DNS Names — defines
.testin the local model as reserved for testing