← DNS SecurityThreat / Critical

DNS Cache Poisoning

An attacker injects forged DNS records into a resolver's cache, silently redirecting users to malicious servers — without any visible sign something is wrong.

The Attack

How Cache Poisoning Works

DNS resolvers cache responses to avoid re-querying authoritative nameservers on every request. Cache poisoning exploits this trust: an attacker races to send a forged response before the legitimate authoritative answer arrives, convincing the resolver to cache a false record.

The attacker's goal is to win the race condition — they must guess the correct 16-bit Transaction ID (TXID) in the resolver's outstanding query before the real answer arrives. With only 65,536 possible TXIDs, a determined attacker can flood a resolver with forged responses until one matches.

Once the poisoned entry is cached, every user who queries that resolver for the poisoned domain gets the attacker's IP address — for the duration of the forged record's TTL. This can be used for credential harvesting, malware distribution, or man-in-the-middle attacks.

65,536
Possible TXIDs
2008
Kaminsky attack
The Kaminsky Attack (2008)Security researcher Dan Kaminsky discovered a practical variant that could poison a resolver in seconds rather than days. By querying random subdomains, he forced the resolver to make continuous new queries — each a new window to inject a forged response. Coordinated patching of all major resolvers was done in secret before disclosure.
Attack Flow

Step-by-Step Cache Poisoning

1

Attacker triggers a query

The attacker sends a query to the target resolver for a name under a domain they control or that will miss cache — forcing the resolver to send a query to the authoritative nameserver.

2

Flood with forged responses

Before the real answer arrives, the attacker sends thousands of forged UDP responses — each with a different guessed TXID — all claiming to be from the authoritative nameserver, all containing a poisoned A record.

3

Race condition: one TXID matches

If one forged response's TXID matches the outstanding query's TXID, the resolver accepts it and caches the attacker's IP for the domain.

4

Real answer discarded

When the legitimate authoritative response arrives, it's ignored — the resolver already has a "cached" answer.

5

All users redirected

Every subsequent query for that domain is answered with the poisoned cache entry. Victims are silently redirected to attacker infrastructure until the TTL expires.

Defenses

Mitigations & Countermeasures

DNSSEC (Primary Defense)

DNSSEC cryptographically signs every DNS record. A validating resolver verifies the signature before caching the response. Even if an attacker injects a forged response, they cannot forge valid signatures without the zone's private key. Validating resolvers return SERVFAIL on failed verification — the poisoned response is never used.

Source Port Randomization (RFC 5452)

After Kaminsky, resolvers began randomizing both the UDP source port (16 bits) AND the TXID (16 bits), creating a 32-bit combined challenge space (4 billion combinations). This makes brute-force guessing impractical without an extremely fast network connection.

0x20 Encoding

Some resolvers randomly capitalize letters in queries (e.g., "ThEdNs.GuRu"). Responses must mirror the exact capitalization to be accepted. Attackers cannot reliably reproduce the correct casing, adding another entropy layer without protocol changes.

DNS-over-TLS / DNS-over-HTTPS

Encrypted DNS transport prevents on-path injection entirely. Attackers cannot inject forged UDP responses into an established TLS session. DoT and DoH also authenticate the resolver's identity, preventing resolver substitution.

Testing

Checking Your Resolver's Defenses

Test DNSSEC validation

# A validating resolver should FAIL this # (deliberately broken DNSSEC) dig dnssec-failed.org A # Expected: SERVFAIL # A non-validating resolver returns an answer # (bad — it accepts forged responses)

Check AD bit (Authenticated Data)

# Query a DNSSEC-signed domain dig thedns.guru A +dnssec # Look for "ad" in the flags line: # flags: qr rd ra ad # ^^ authenticated data # No "ad" = resolver not validating

Test source port randomization

# Cloudflare DNSSEC test # https://1.1.1.1/help # Shows: DNSSEC validation status # DNS Flag Day test dig +short TXT \ _dnssec.your-resolver-ip.dnsflagday.net

Verify resolver with delv

# delv = DNS lookup & validation tool # (part of BIND 9.10+) delv thedns.guru A +vtrace # Shows full validation chain # from root → TLD → authoritative