In this lesson, you will learn how to defend your Node.js applications against DNS rebinding by strictly validating the Host header to ensure requests are routed to the intended backend.
Understanding the Threat
A DNS rebinding attack exploits the browser's trust in a domain. An attacker tricks a victim's browser into visiting a malicious site that uses a very short DNS Time-to-Live (TTL). Once the browser resolves the domain to an attacker-controlled IP, the attacker's script then triggers a new request to the same domain. Because the DNS entry has expired, the browser re-resolves the domain—this time to a private, internal IP (like 127.0.0.1 or a private cloud metadata service). Since the domain matches, the browser bypasses Same-Origin Policy (SOP) checks, allowing the attacker to interact with your internal services.
Implementing Host-Header Validation
In Node.js, your server must verify that the incoming Host header matches an expected value (your production domain) rather than assuming the header is legitimate. If the header does not match your environment’s authorized list, the server should reject the request immediately.
Here is a basic implementation using Express:
const ALLOWED_HOSTS = ['api.myapp.com', 'myapp.com'];
app.use((req, res, next) => {
const host = req.get('Host');
if (!ALLOWED_HOSTS.includes(host)) {
// Log the suspicious attempt and reject
console.error(`Blocked suspicious Host header: ${host}`);
return res.status(403).send('Forbidden: Invalid Host header.');
}
next();
});
Why this works
By enforcing this whitelist, you prevent the application from processing requests meant for an internal loopback or private network service. Even if an attacker successfully manipulates the DNS resolution to point to your local IP address, your server will see a Host header matching the attacker's domain (or no host at all) and will block the interaction before any sensitive data is exposed or internal actions are triggered.
Always ensure your server is configured to reject requests without a Host header, as HTTP/1.1 requires this field and missing it is a common hallmark of automated scanning and rebinding attempts.
Key Takeaway: Never implicitly trust the Host header; strictly validate it against an allow-list of your known production domains to neutralize DNS rebinding attempts.