Skip to main content
友田 陽大
実践ネットワーク攻撃と防御
セキュリティ
ネットワーク
TCP/IP
脆弱性診断
ホワイトハッカー
倫理的ハッキング

The mechanism and defense of DNS spoofing and cache poisoning [2026] — protect name resolution with RFC 5452 and DNSSEC

A systematic explanation of DNS spoofing / cache poisoning that hijacks name resolution, from the principle of the Kaminsky attack to the defenses of RFC 5452 and DNSSEC (RFC 4033-4035). Why UDP DNS believes forged answers, how source-port randomization and the transaction ID create unpredictability, and DNSSEC signature verification and encryption via DoH/DoT — shown with type-safe code and configuration examples. All are legal procedures confined to your own resolver.

Published
Reading time
8 min read
Author
友田 陽大
Share

The instant you type bank.example into your browser, the first thing that happens is name resolution — a DNS query that converts the domain name into an IP address. What if this one move is hijacked by an attacker? With the correct domain still shown in the URL bar, only the connection destination is swapped to the attacker's server. This is DNS spoofing, and cache poisoning, which poisons the resolver's cache itself, is an extremely wide-reaching attack that drags in many users with a single success.

Following the big picture of network pentesting, this article unpacks the principle of DNS attacks from the historic Kaminsky attack and shows defense via RFC 5452 and DNSSEC with configuration and code. At the root is TCP/IP's premise of trust that early DNS believes an "unauthenticated response" over UDP.

Thoroughness of the safe zone: all verification in this article is done only against a DNS resolver you stood up yourself (e.g. a local BIND/Unbound experiment box) in an isolated lab. Injecting forged answers into a public resolver or someone else's DNS is a violation of the Unauthorized Access Act and an attack on social infrastructure. What you may verify is only your own assets — always read the legal article first.


1. How DNS gets tricked — "a fast, plausible forged answer"

When a caching DNS resolver receives a query for bank.example not yet in its cache, it queries the upstream authoritative server. The attacker's aim is to make the resolver believe a forged response before the legitimate authoritative server's response.

For the resolver to accept the forged answer, the forged answer must satisfy all of the following.

正規応答とマッチさせるべき要素:
  1. トランザクションID(16ビット)が問い合わせと一致
  2. 送信元/宛先ポートが一致
  3. 質問セクション(QNAME/QTYPE)が一致
  4. 正規応答より「速く」届く(レース)

Resolvers once fixed the source port, and there were implementations where the transaction ID was easy to predict. Then what the attacker must guess is effectively just the 16-bit ID (65,536 possibilities). Furthermore, if it's cached, you have to wait until the next TTL, but —

1.1 The Kaminsky attack (2008) — the single blow that forced DNS to be redesigned

In 2008, Dan Kaminsky disclosed a decisive method. Query a large number of non-existent subdomains (random123.bank.example) and, for each, fire a forged answer containing a delegation (NS/glue) saying "the authoritative server for bank.example is the attacker's IP." Because the names don't exist, you can avoid waiting for the cache TTL and try at high speed any number of times. Once you hit, the authority for the entire domain is etched into the cache as poison.

This showed "guessing the 16-bit ID can realistically be broken" and forced a fundamental rethink of DNS defense. The answers are the following RFC 5452 and DNSSEC.


2. Defense ①: RFC 5452 — make guessing "impractical"

RFC 5452 (Measures for Making DNS More Resilient against Forged Answers, 2009) standardized implementation rules that make forged answers hard to accept. The center is adding entropy.

  • Source-port randomization: choose the source UDP port randomly per query. The attacker must guess the port (up to 16 bits) in addition to the ID, so the combined entropy jumps to effectively about 32 bits. Brute force becomes impractical.
  • Transaction-ID randomization: avoid predictable IDs and randomize them cryptographically.
  • 0x20 encoding (auxiliary): randomize the case of letters in QNAME and use whether it's preserved in the response as additional verification material.
# 自分のリゾルバが送信元ポートをランダム化しているかを確認(自分の資産で)
# 良い例:問い合わせごとに source port がばらける(高エントロピー)
dig +short porttest.dns-oarc.net TXT @127.0.0.1
#   → "GREAT" 等(リゾルバのポートランダム性の評価が返る)

An important limitation: RFC 5452 is a probabilistic defense that "makes guessing hard," not one that "makes it impossible." Entropy is meaningless against an attacker on the path (already MITM). So the next, DNSSEC, is needed.


3. Defense ②: DNSSEC — end "first to say it wins" with cryptography

DNSSEC (RFC 4033/4034/4035) is the essential answer to DNS attacks. The idea is clear — authoritative servers digitally sign responses, and the resolver verifies that signature. Forged answers can't produce a correct signature, so they're rejected at verification.

DNSSEC の信頼の連鎖(chain of trust):
  ルート(.) の鍵 ──署名──► .example の鍵 ──署名──► bank.example のレコード
       ▲                                                    │
       └──── リゾルバはルートの鍵(トラストアンカー)から ◄────┘
              署名を辿って検証。1つでも署名が合わなければ SERVFAIL(拒否)
  • RRSIG: the signature over each record set.
  • DNSKEY: the public key used for verification.
  • DS: placed in the parent zone, guaranteeing the child zone's key (the link of the chain).

When verification succeeds, the AD (Authenticated Data) bit is set in the response. Forged answers fail signature verification, and the resolver returns no result.

# DNSSEC 検証が効いているかを確認(AD フラグが立つか)
dig +dnssec bank.example @127.0.0.1
#   ヘッダの flags に "ad" があれば、署名検証済みの真正な応答
#   RRSIG レコードが応答に含まれる

3.1 "Require" verification on the app/resolver side

Even if the authoritative zone is signed, it's meaningless unless the resolver verifies. Using a verifying resolver is the user side's responsibility.

import { Resolver } from "node:dns/promises";

/**
 * DNSSEC 検証を行うリゾルバ(例:ローカルの validating resolver)を明示的に指定する。
 * OS のデフォルトに任せず「検証するリゾルバ」へ向けることで、毒入りキャッシュを避ける。
 * 失敗(SERVFAIL)は握りつぶさず例外として扱い、安全側(接続しない)に倒す。
 */
export async function resolveValidated(hostname: string): Promise<readonly string[]> {
  const resolver = new Resolver();
  resolver.setServers(["127.0.0.1"]); // 検証する自前/信頼リゾルバ(Unbound 等)
  try {
    return await resolver.resolve4(hostname);
  } catch (err) {
    // SERVFAIL は「署名検証に失敗した可能性」を含む。曖昧なまま接続しない。
    throw new Error(`DNS resolution failed (possible DNSSEC failure) for ${hostname}: ${(err as Error).message}`);
  }
}

4. Defense ③: DoH / DoT — encrypt the path

DNSSEC protects the authenticity (whether it's been tampered with) of the response, but not its confidentiality (so others can't peek at who looked up what). Also, the route from the user to the resolver is still plaintext. What fills this is path encryption.

  • DoT (DNS over TLS, RFC 7858): carry DNS over TLS (port 853).
  • DoH (DNS over HTTPS, RFC 8484): carry DNS over HTTPS (443). Strong against censorship and sniffing.
役割分担(両方が要る):
  DNSSEC  … 応答の真正性(偽答を弾く)        ← 権威〜リゾルバの「中身」を守る
  DoH/DoT … 経路の機密性・完全性(盗聴/改ざん) ← 利用者〜リゾルバの「経路」を守る

DNSSEC and DoH/DoT are complementary, not competing. The former is "is the answer genuine," the latter is "is the path being peeked at." In production, combine both.


5. A checklist for designers

Points to confirm in design and operations to protect your domain and name resolution.

  • Is your authoritative zone DNSSEC-signed (register the DS with the parent via your domain registrar/DNS service).
  • Does the resolver your app points at perform DNSSEC verification (for a managed resolver, confirm the verification policy).
  • Does the resolver randomize the source port (RFC 5452-compliant).
  • Can you use DoH/DoT between client and resolver.
  • Do you not swallow DNS resolution failures (SERVFAIL) and fall to the safe side (abort connection).
  • After all, the final wall is TLS certificate verification — even if name resolution is poisoned, TLS won't connect to an attacker's server lacking a legitimate certificate (see the MITM article).

Think in layers: even if DNS is poisoned, TLS protects; the MITM targeting TLS is protected by mTLS and zero trust. Not depending on a single defense is the consistent stance of network security.


6. Summary

  • DNS spoofing/cache poisoning hijacks name resolution. The Kaminsky attack made the danger of 16-bit ID guessing real and forced a redesign of DNS defense.
  • RFC 5452: source-port + ID randomization raises entropy to the ~32-bit class. A probabilistic defense that makes guessing impractical (powerless against an on-path attacker).
  • DNSSEC (RFC 4033-4035): an essential defense that rejects forged answers via signatures and a chain of trust. The AD bit is proof of authenticity.
  • DoH/DoT (RFC 7858/8484): path encryption. Complementary to DNSSEC (authenticity); you need both.
  • In the end, TLS again: even if name resolution is poisoned, certificate verification refuses the attacker's server. Defense in depth.

Next, we'll handle TCP session hijacking / RST injection / IP spoofing, which seizes the established TCP connection itself, including defense via RFC 5961.


I (Hinata Tomoda) have implemented production DNS design (DNSSEC, private DNS, fail-safe on resolution failure) and "don't fully trust name resolution" designs including TLS/certificate operations. "I want to DNSSEC-sign our domain," "DNS resolution failures are causing outages," "I want to introduce DoH/DoT" — I diagnose such hardening of name resolution from the attacker's perspective and implement it with the two wheels of authenticity and confidentiality. Feel free to reach out.

友田

友田 陽大

Developer of a METI Minister's Award–winning product. With TypeScript + Python + AWS, I deliver SaaS, industry DX, and production-grade generative AI (RAG) end to end — from requirements to infrastructure and operations — single-handedly.

Could this attack succeed on your network?

Network / infrastructure penetration testing & hardening

The L2–L4 attacks covered here — ARP spoofing, DNS poisoning, session hijacking, SYN flood, sniffing — I diagnose where your configuration breaks from an attacker's perspective, and design and implement RFC-compliant defenses (DAI, DNSSEC, RFC 5961, BCP 38, TLS/mTLS, WAF/DDoS protection). With experience building multi-layered networks on AWS multi-account (VPC, least-privilege IAM, GuardDuty, WAF), I help minimize the attack surface and move toward zero trust.

Available for both project-based (contract) and advisory engagements. Start with a free 30-minute consult.

Also worth reading