Back to guides
Concept

A Forged Answer Only Has to Arrive First.

Plain DNS has no way to tell a real answer from a fake one. It simply accepts the first reply that matches the question it asked. If an attacker can slip a forged reply in before the genuine one arrives, the resolver believes it, caches it, and hands the same lie to everyone who asks next. That is DNS spoofing, and when the forgery sticks in the cache it becomes cache poisoning.

PLAIN DNS ACCEPTS THE FIRST MATCHING REPLY Your resolver keeps the first match Real nameserver the honest answer Attacker floods guessed forgeries cached: 6.6.6.6 forged answer accepted real reply arrives too late, discarded as a duplicate everyone is now sent to the attacker

The attacker does not need to break encryption or beat the real server every time. It only needs one forged reply to land first and match the query. Once cached, that answer is served to every user until it expires.

The whole attack rests on one design flaw in classic DNS: an answer carries no proof of who sent it. Beat the real server to the resolver with a believable forgery, and the resolver cannot tell the difference.

Two names for one problem

DNS spoofing - a single forged reply
Sending a fake DNS answer that pretends to come from the real nameserver, hoping it reaches the target before the genuine one. It is the act of forging a reply, whether it is aimed at one device on a shared network or at a resolver.
Cache poisoning - the forgery that sticks
A resolver stores answers for a while so it can reply quickly, governed by each record's time to live. When a spoofed answer is accepted and stored, the resolver keeps serving that forgery to everyone who asks, with no further effort from the attacker, until the entry expires. One lucky forgery becomes a lasting redirect.

How the forgery wins the race

When your resolver does not already have an answer cached, it asks the authoritative nameservers for the name and waits for a reply. Classic DNS rides on UDP, a fire-and-forget transport with no handshake, so a reply is accepted as long as it looks like it answers the right question. To match, a reply has to land on the same network port the resolver used and carry the same 16-bit transaction ID the resolver put in the query. That is the entire lock on the door.

An attacker who cannot see the query has to guess those values, then send a burst of forged replies hoping one matches before the real server responds. For years the odds were far better than they should have been: many resolvers reused a predictable port and stepped the transaction ID up by one each time, leaving only a small space to guess. In 2008 Dan Kaminsky showed how to make the race winnable at scale by forcing a resolver to look up many fresh names in a row, getting a fresh shot at the guess each time, and forging answers that also rewrote where a whole domain's nameservers lived. That turned a long-shot guess into a practical way to hijack an entire domain.

There is an easier version too. On a network you share, such as open Wi-Fi, an attacker who can see your queries does not have to guess anything; they can read the port and ID straight off the wire and answer faster than the real server. That is why an untrusted local network is the classic place spoofing happens, and why the link between you and your resolver matters as much as the resolver's own defenses.

Why a wrong address is dangerous

A poisoned answer does not look like an error. The address bar still shows the name you typed, because the name is correct; only the address behind it has been swapped. Point that at a bank, an email provider, or a software update server, and people land on a server the attacker controls while everything on screen looks normal. Passwords get entered, updates get replaced, sessions get captured, and nothing warns the user.

HTTPS catches a lot of this, because the impostor would also need a valid certificate for the real name, and a browser will refuse and warn if it cannot prove it. That is a real and important backstop. But it is not the whole story: not every service is on the web, certificate checks can be bypassed or stripped in some setups, and a warning the user clicks through still ends with them on the wrong server. The cleaner fix is to stop the forged answer from being believed in the first place.

The layers that stop it

No single setting closes the whole gap. Spoofing is beaten by stacking defenses that each make the forgery harder or make it provably fail. Here is what each one covers.

Defense What it does What it leaves open
Port and ID randomization Picks a random source port and transaction ID per query, widening the space an attacker must guess from thousands to billions Makes blind guessing impractical, but does not help against an attacker who can read the query on a shared network
0x20 case randomization Randomly mixes the upper and lower case of the queried name, adding more bits the forgery has to echo back exactly Another guessing hurdle, not a proof of authenticity
Encrypted transport DoH, DoT, DoQ and DNSCrypt wrap the link between you and your resolver, so a local attacker cannot read the query or inject a reply on that hop Protects the you-to-resolver link only; says nothing about whether the resolver's own answer is genuine
DNSSEC validation The domain signs its records, so a validating resolver can check the signature and reject any answer that was forged or altered Only works for zones that are signed; it authenticates answers, it does not hide them

The first two make the race nearly impossible to win by luck. Encrypted transport removes the easy local attack. DNSSEC is the one that proves an answer is real rather than just hard to forge.

Why DNSSEC is the answer that actually proves itself

Randomizing ports and case changes the odds; it does not change the fact that the resolver still cannot tell a real answer from a fake one, only that the fake is harder to land. DNSSEC changes that fact directly. Each record is signed with a key only the domain holds, and the signatures chain back to the root, so a validating resolver can verify that the answer is exactly what the domain published. A forged reply has no valid signature, so it fails the check and is thrown away instead of cached. The race stops mattering, because winning it no longer produces an answer the resolver will believe.

If you want to see that defense end to end, the validating resolver runbook sets up a resolver that checks every signature itself rather than trusting one upstream to have done it. That is the difference between a resolver that merely accepts answers and one that verifies them.

Does encrypted DNS stop spoofing?

Partly, and it is worth being precise about which part. Encrypted DNS protects the single hop between your device and your resolver. On that hop a local attacker can no longer read your query or forge a reply, which shuts down the easy open-Wi-Fi version of the attack and is a genuine improvement over plain DNS. It also keeps that link private, which is the separate job covered in what your ISP can still see.

What it does not do is vouch for the answer itself. Once your encrypted query reaches the resolver, the resolver still has to go out and resolve the name, and that onward traffic is where poisoning happens. Privacy on the wire and authenticity of the answer are two different guarantees: encryption hides the question, DNSSEC proves the answer. A strong setup uses both, which is why this service runs encrypted transport and validates DNSSEC rather than picking one.

Encrypted on the wire, validated at the source

Point your device at a resolver that encrypts the link so a local attacker cannot forge a reply, and validates DNSSEC so a poisoned answer fails the check instead of reaching you.

Set up encrypted, validating DNS

New here? Start with what a DNS resolver is, then read what DNSSEC is for the defense side of this attack.