DNS Rebinding Attack
debt(d7/e5/b5/t7)
Closest to 'only careful code review or runtime testing' (d7). The term's detection_hints list semgrep but explicitly marks automated detection as 'no'. The code pattern requires identifying that hostname validation occurs but resolved IP is not checked against private ranges — this is a semantic vulnerability that requires understanding the request flow and timing of DNS resolution. Standard linters won't catch it; even SAST tools struggle without custom rules targeting this specific pattern.
Closest to 'touches multiple files / significant refactor in one component' (e5). The quick_fix states 'Validate the resolved IP address of user-supplied URLs, not just the hostname — reject requests to private IP ranges'. While conceptually a single validation step, implementing this correctly requires modifying HTTP client wrappers, adding IP validation at connection time (not just before), and potentially implementing DNS pinning. This typically touches request handling infrastructure across the codebase.
Closest to 'persistent productivity tax' (b5). The applies_to field indicates this affects web and api contexts broadly. Once you implement IP validation for user-supplied URLs, every new HTTP client usage, webhook handler, or URL fetch feature must route through the validated path. This creates an ongoing tax on development — any bypass of the validation layer reintroduces the vulnerability. It's not architectural rework, but it shapes how all outbound requests must be handled.
Closest to 'serious trap - contradicts how similar concepts work elsewhere' (t7). The misconception field explicitly states developers believe 'DNS rebinding only affects poorly configured internal networks' when in fact 'It bypasses the browser same-origin policy to reach localhost services, IoT devices, and cloud metadata endpoints regardless of network configuration.' Developers familiar with hostname-based validation assume DNS resolution is stable between check and use — this contradicts the mental model that validating a hostname once is sufficient.
Also Known As
TL;DR
Explanation
DNS rebinding works in two phases. First, the victim visits attacker.com — the DNS record has a short TTL. After the page loads, the attacker changes the DNS record to point to an internal IP (192.168.x.x or 127.0.0.1). The browser now considers requests to attacker.com as same-origin for that internal address, allowing JavaScript to query internal services — admin panels, routers, cloud metadata endpoints (169.254.169.254). Defences include: validate the Host header server-side against an allowlist, bind internal services only to loopback, use private DNS resolvers that refuse to resolve public domains to private IPs, and implement network segmentation.
Common Misconception
Why It Matters
Common Mistakes
- Not re-validating the resolved IP at connection time after an initial DNS-based allowlist check.
- Trusting the Host header for routing to internal services without IP-level validation.
- Not using DNS TTL pinning or short-lived DNS caching protections.
- Internal services that accept requests from any source, assuming the network perimeter is sufficient protection.
Code Examples
// Validate hostname but not resolved IP — vulnerable to rebinding:
$url = $_GET['webhook'];
$host = parse_url($url, PHP_URL_HOST);
if (!in_array($host, $allowed_hosts)) die('Blocked');
curl_exec(/* $url — DNS may now resolve to 192.168.1.1 */);
# DNS rebinding bypasses Same-Origin Policy for internal services
# attacker.com resolves to attacker's server, then rebinds to 127.0.0.1
# Prevention:
# 1. Validate Host header — reject unexpected values
$allowed = ['yourapp.com', 'www.yourapp.com'];
if (!in_array($_SERVER['HTTP_HOST'] ?? '', $allowed, true)) {
http_response_code(400); exit;
}
# 2. Bind internal services to 127.0.0.1 only, not 0.0.0.0
# php -S 127.0.0.1:8000 (dev server)
# 3. Require auth tokens even on internal-only endpoints
# 4. Modern browsers block rebinding to private IPs for public domains
# — partial protection, don't rely on it