Skip to content

v1.7.3

Choose a tag to compare

@semihalev semihalev released this 19 Jul 17:45
· 91 commits to main since this release
6f745fe

A security release fixing two reported advisories and two additional DNSSEC forgery vectors. Recommended for all deployments — validating resolvers should upgrade promptly.

Security advisories

  • CD-bit cache poisoning (GHSA-g5mh-6738-qgh9, High). A single CD=1 query for a Bogus (validation-failing) name cached the unvalidated answer and served it as NOERROR to validating CD=0 clients — a DNSSEC downgrade any client of a shared resolver could trigger. Cache state is now strictly isolated across the CD bit: delegations are keyed on the client's CD bit only and the cross-CD fallback that leaked unvalidated CD=1 results into CD=0 answers is gone. The same change fixes a prefetch path that could refresh a cached answer without re-validation and silently drop AD. (#505)
  • Ghost/phoenix domain attack (GHSA-mqfw-f48p-2vc8, Medium). A withdrawn child zone could be kept resolving indefinitely: the delegation cache floored parent referral TTLs to one hour and prefetch kept renewing the lease, so the parent's NXDOMAIN was never observed. Fixed in three layers: the parent-granted delegation TTL is honoured verbatim as one absolute deadline that validation and NS-lookup time count against (#513); nested delegations inherit the shallowest ancestor deadline on the path, so a deep 12h referral cannot outlive the 3s ancestor lease that granted it (#514); and every cached answer is bound to its delegation cut — effective lifetime is min(answer TTL, cut deadline) enforced at read time, with the prefetch write-back made CAS so a stale refresh cannot resurrect an expired lease (#515). The full design is committed at docs/security/ghost-phoenix-durable-design.md.

DNSSEC hardening

  • Require wildcard-denial proof on positive answers (RFC 4035 §5.3.4). A zone's legitimately-signed wildcard RRSIG could be replayed over a concrete name that really exists and returned with AD=1 — RRSIG verification alone accepts it. Wildcard-expanded answers now additionally require an NSEC/NSEC3 proving the next closer name does not exist. (#512)
  • Reject exact-owner NSEC3 matches as denial coverage (RFC 5155). miekg/dns NSEC3.Cover() accepts a hash equal to the owner inside an ordinary interval, so an NSEC3 proving a name exists was accepted as proof it doesn't — enabling forged authenticated NXDOMAINs and bypassing the wildcard next-closer check above. Coverage is now strict: exact owner matches are excluded at every NSEC3 coverage call site. (#516)

Fixes

  • False SERVFAILs for insecure names served by multi-zone authorities (e.g. tether.edge.apple, #506): when a server authoritative for several zones of the chain answers with no referral crossed, the insecure-delegation proof demanded an exact-match NSEC3 that opt-out zones cannot have by definition — and the resulting SERVFAIL latched in the negative cache. Opt-out delegations are now proven via the RFC 5155 §8.6 covering path. (#507)

Build

  • Toolchain bumped to go1.26.5; routine dependency and CI-action bumps. (#504, #508, #509, #510, #511)

Thanks

Thanks to @MaciejTe for reporting and providing a clean PoC for the CD-bit cache poisoning, and to @Bubb1eGvm for reporting the ghost-domain attack — both reported responsibly through GitHub private vulnerability reporting.

Full changelog: v1.7.2...v1.7.3