DNS cache poisoning is a technique where an attacker inserts forged DNS responses into a resolver's cache, causing it to return a malicious IP address for legitimate domain queries. The poisoned entry persists until the cache TTL expires, silently redirecting every user who queries that resolver to an attacker-controlled server. It is one of the most dangerous DNS attacks because it is invisible to the end user — the browser still shows the correct domain name.
I have always considered cache poisoning the most elegant DNS attack because it exploits the protocol's core assumption: that responses are trustworthy. Understanding how it works is essential for anyone managing DNS infrastructure.
How DNS Caching Works
Before understanding the attack, you need to understand the mechanism it exploits.
When a recursive resolver receives a query for a domain it has not seen before, it walks the DNS hierarchy — root servers, TLD servers, authoritative servers — to find the answer. Once it has the response, it stores it in its cache for the duration specified by the TTL (Time to Live) value in the response.
Subsequent queries for the same domain are answered directly from cache, without contacting any upstream servers. This is what makes DNS fast. It is also what makes cache poisoning so effective — a single forged entry serves every subsequent query.
How Cache Poisoning Works
The attack exploits a race condition in DNS resolution:
-
Trigger the query. The attacker causes the target resolver to look up a domain. This can be as simple as sending an email with an image hosted on a domain the resolver has not cached.
-
Flood with forged responses. Before the legitimate authoritative server responds, the attacker floods the resolver with forged DNS responses. Each forged packet contains the attacker's IP address as the answer.
-
Match the transaction ID. Every DNS query includes a 16-bit transaction ID. The resolver only accepts a response whose transaction ID matches the query it sent. The attacker must guess this value. With only 65,536 possibilities, brute force is feasible.
-
Win the race. If one of the attacker's forged packets arrives before the legitimate response and matches the transaction ID (and source port, if randomized), the resolver accepts it and caches the malicious answer.
-
Persistence. The poisoned entry remains in cache for the duration of the TTL, redirecting all users who query that domain.
The Kaminsky Attack
In 2008, Dan Kaminsky demonstrated a devastating improvement to the basic cache poisoning technique that made it dramatically more reliable.
The classic attack has a fundamental limitation: you get one attempt per TTL period. If the domain is already cached, you have to wait for the cache entry to expire before trying again. And each attempt has only a 1-in-65,536 chance of guessing the transaction ID correctly.
Kaminsky's insight was to target random subdomains instead:
- Query the resolver for
random001.example.com— a name that is guaranteed not to be in cache - Flood forged responses that include a malicious authority section delegating
example.comto the attacker's nameserver - If the attempt fails, immediately try
random002.example.com— a fresh query with a fresh transaction ID
This allows hundreds of attempts per second. The attacker is no longer limited by TTL. As soon as one forged response is accepted, the resolver's entire cache for example.com is compromised because the authority section overrides the real delegation.
Real-World Impact
The Kaminsky attack was so serious that a coordinated disclosure involved every major DNS software vendor simultaneously releasing patches. Before those patches, any recursive resolver on the internet was vulnerable.
Cache poisoning has been used in the wild for:
- Redirecting banking websites to credential-harvesting phishing pages
- Intercepting email by poisoning MX record lookups
- Distributing malware by redirecting software update domains
- Undermining TLS by redirecting certificate validation queries (though modern browsers mitigate this with certificate pinning and CT logs)
How Attackers Discover This Weakness
An attacker evaluates a target resolver by checking:
# Check if the resolver performs source port randomization
dig +short porttest.dns-oarc.net TXT @target-resolver
If the resolver uses a predictable source port, the attack becomes trivially easy because the attacker only needs to guess the 16-bit transaction ID, not the source port.
The attacker also checks whether the resolver validates DNSSEC:
dig +dnssec +cd sigfail.verteiltesysteme.net @target-resolver
If the resolver returns a result even with the +cd (checking disabled) flag, and does NOT return SERVFAIL without it for known-bad DNSSEC domains, the resolver does not validate signatures and is vulnerable.
How to Test Your Own Resolver
You should verify that your resolvers are resistant to cache poisoning:
Test source port randomization:
dig +short porttest.dns-oarc.net TXT @your-resolver
The response will tell you whether your resolver uses good port randomization. "GREAT" is what you want to see.
Test DNSSEC validation:
dig +dnssec example.com @your-resolver
Look for RRSIG records in the response. Their presence means the resolver is at least DNSSEC-aware. For full validation testing, query a domain with intentionally broken DNSSEC:
dig sigfail.verteiltesysteme.net A @your-resolver
If the resolver returns SERVFAIL, it is correctly rejecting invalid DNSSEC signatures. If it returns an answer, validation is not enforced.
You can also use the DNS Inspector to check whether your domain's DNSSEC records are properly configured.
How to Defend Against It
Enable DNSSEC
DNSSEC is the definitive defense against cache poisoning. It adds cryptographic signatures to DNS responses, allowing resolvers to verify that the data has not been tampered with. A forged response without valid RRSIG records will be rejected.
If you manage domains, sign them with DNSSEC. If you manage resolvers, enable DNSSEC validation. For a full walkthrough, see my article on What Is DNSSEC and Why Should You Enable It.
Source Port Randomization
Modern resolvers randomize the UDP source port for outgoing queries. This adds approximately 16 bits of entropy on top of the transaction ID, making brute force exponentially harder. Ensure your resolver software is up to date and that NAT devices in front of it are not de-randomizing ports.
DNS Cookies (RFC 7873)
DNS cookies add a lightweight authentication mechanism to DNS queries. The resolver and server exchange cryptographic tokens that an attacker cannot forge without observing the traffic. This effectively eliminates off-path cache poisoning.
Response Rate Limiting
Rate limiting the number of identical responses a server will send reduces the attacker's ability to generate the volume needed for brute force attempts.
Mitigation Checklist
- DNSSEC validation is enabled on all recursive resolvers
- DNSSEC signing is enabled on all authoritative domains
- Source port randomization is confirmed working
- DNS cookies are enabled where supported
- Resolver software is patched and current
- NAT devices are not de-randomizing source ports
- Response rate limiting is configured on authoritative servers
- Monitoring is in place for unusual cache behavior
Common Misconfigurations
- Running outdated resolver software that does not randomize source ports
- NAT gateways that remap source ports to sequential values, undoing randomization
- Disabling DNSSEC validation because it "causes problems" — usually a sign of broken DNSSEC on specific domains, not a reason to disable validation globally
- Not signing your own domains even though your resolvers validate — you are protected from poisoning but your users on other resolvers are not
Ethical Note
Testing cache poisoning against resolvers you do not own is illegal and unethical. The techniques described here should only be used for testing your own infrastructure or in authorized security assessments. For practice, set up a local resolver in a virtual environment and test against it.
This article is part of the Complete Guide to DNS Attacks and DNS Security. See also: DNS Hijacking, DNSSEC Downgrade Attack.
