← Back to Feed CACHED · 2026-10-22 12:02:31 · CACHE_KEY CVE-2026-97313
CVE-2026-97313 · CWE-617 · Disclosed 2026-10-21

ISC BIND RPZ query resumption assertion failure with mixed recursive-only policies

ASSESSED — NOISGATE
Vendor
—
—
—
Reassessed
—
—
—
Verdict: —
Do you agree?
01 · The Real Story

Like a fire alarm that only goes off in buildings wired with two competing smoke-detector brands

CVE-2026-97313 is a remotely-triggerable assertion failure (CWE-617) in ISC BIND 9 recursive resolvers. An unauthenticated attacker sends a query with RD=1 (recursion desired) followed by a second query with RD=0 (no recursion). If the server has two or more RPZ zones where at least one uses the default recursive-only yes and another explicitly sets recursive-only no, the RPZ query-resumption path in rpz_rrset_find() hits an INSIST(st->r.r_type == type) invariant violation at lib/ns/query.c:2845, and named exits. The crash is deterministic once the config precondition is met. Affected versions span BIND 9.16.0–99.18.50, 9.20.0–9.20.29, 9.21.0–9.21.26, plus corresponding -S1 Supported Preview editions. Fixed in 9.20.30 and 9.21.27. Debian Trixie has already backported the fix via DSA-6576-1.

ISC rates this HIGH 7.5 with CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H. The vector is technically correct—the crash *is* network-reachable, unauthenticated, and low-complexity *given* you hit a vulnerable instance. But CVSS cannot encode the configuration prerequisite. RPZ is a minority feature; mixed recursive-only settings across RPZ zones is rarer still. The vendor severity overstates the real-world risk for most BIND operators. This is a configuration-gated DoS, not a universal BIND crash. noisgate downgrades to MEDIUM 5.5.

"DNS crash needs a rare RPZ config most shops dont run; downgrade to MEDIUM."
02 · The Attack Path

5 steps from start to impact.

STEP 01

Identify a reachable BIND recursive resolver

The attacker locates a BIND instance accepting recursive queries. On the public internet this means open resolvers; inside an enterprise it means the internal DNS tier. Tools like dig +recurse @target or Shodan/Censys product:BIND queries reveal candidates. The resolver must be reachable on port 53 UDP/TCP.
Conditions required:
  • Target runs BIND 9.16.0–9.18.50, 9.20.0–9.20.29, or 9.21.0–9.21.26
  • Attacker can send DNS queries to the resolver (port 53 reachable)
Where this breaks in practice:
  • Well-managed enterprises restrict recursive DNS to internal clients via ACLs (allow-recursion), blocking external attackers
  • Cloud-hosted authoritative DNS (Route 53, Cloudflare, etc.) is not BIND and is unaffected
Detection/coverage: Shodan/Censys fingerprinting for BIND version banners; named -v locally
STEP 02

Confirm RPZ with mixed recursive-only settings

The vulnerability requires ≥2 RPZ zones with differing recursive-only values. The attacker cannot remotely confirm this configuration—it is a blind prerequisite. Most RPZ deployments use the default (recursive-only yes) on all zones. Having at least one zone set to recursive-only no is a deliberate, non-default choice made for specific policy reasons (e.g., applying RPZ to non-recursive stub/forwarded queries).
Conditions required:
  • Server has ≥2 RPZ zones configured
  • At least one zone has recursive-only no (non-default)
  • At least one zone retains recursive-only yes (default)
Where this breaks in practice:
  • RPZ itself is a minority feature—most BIND deployments are authoritative-only or use simple recursion without RPZ
  • Mixed recursive-only across zones is an unusual, intentional configuration
  • Attacker has no way to fingerprint this remotely—must spray blindly
Detection/coverage: Configuration audit: grep -c 'recursive-only no' named.conf
STEP 03

Send RD=1 query to prime the RPZ lookup

The attacker sends a DNS query with the Recursion Desired flag set (RD=1) for a name that triggers RPZ evaluation requiring an asynchronous fetch (e.g., NSDNAME or NSIP policy lookup). This primes the internal state machine (st->r.r_type) for a recursive RPZ resolution path. Standard tools like dig +recurse suffice.
Conditions required:
  • Query must trigger an RPZ policy that requires an async fetch (NSDNAME/NSIP)
  • The RPZ zone handling this query must have recursive-only yes
Where this breaks in practice:
  • Attacker must guess or know a domain name that triggers the right RPZ policy path
  • Simple passthru or QNAME-only RPZ policies do not trigger the async path
Detection/coverage: DNS query logging (querylog yes) will capture the sequence; SIEM correlation on rapid RD-flip patterns
STEP 04

Send RD=0 query to trigger the assertion failure

While the async RPZ fetch from step 3 is still pending, the attacker sends a second query for the same name but with RD=0. When fetch_callback() completes and restores recursion settings, the RPZ evaluation resumes with inconsistent eligibility state. The INSIST(st->r.r_type == type) check at query.c:2845 fails, and named calls abort(). The process exits immediately.
Conditions required:
  • The second query arrives while the async fetch from step 3 is still in flight
  • Both queries are for the same QNAME so they share the RPZ state
Where this breaks in practice:
  • Timing window is narrow—the async fetch must still be pending
  • Network jitter and resolver caching may close the window before the second query arrives
Detection/coverage: The crash produces a clear log signature: INSIST(st->r.r_type == type) failed followed by exiting (due to assertion failure); monitor for named restarts via systemd journal
STEP 05

Repeat to sustain denial of service

Since systemd or a process supervisor will restart named within seconds, the attacker must repeat the two-query sequence continuously to maintain the outage. Each crash-restart cycle takes 5–30 seconds depending on zone load size. A sustained attack requires persistent network access and knowledge of the triggering QNAME.
Conditions required:
  • Persistent network access to the resolver
  • Knowledge of a QNAME that triggers the vulnerable RPZ async path
Where this breaks in practice:
  • Rate-limiting on DNS queries (RRL) may throttle the attacker
  • Monitoring will quickly detect repeated named crashes and trigger incident response
  • Failover to a secondary resolver (if configured) limits blast radius
Detection/coverage: Repeated crash-restart pattern is trivially detectable; alerting on named exit codes or systemd restart-count thresholds
03 · Compensating Control

1
MEDIUM 5.5→IGNORE 0.0
SEVERITY REDUCED
Audit and unify RPZ recursive-only settings — Review your named.conf for response-policy blocks. If all RPZ zones can use the default recursive-only yes, remove any explicit recursive-only no directives. This eliminates the vulnerability precondition entirely without upgrading BIND. As a MEDIUM verdict, the noisgate remediation SLA is 365 days, but this config change can be deployed immediately with minimal risk.
2
MEDIUM 5.5→LOW 3.0
SEVERITY REDUCED
Restrict recursive query access with ACLs — Ensure allow-recursion and allow-query limit recursive resolution to trusted internal subnets only. This prevents external attackers from reaching the vulnerable code path. Does not protect against malicious insiders or compromised internal hosts. Deploy within standard change-management windows.
3
MEDIUM 5.5→LOW 2.5
SEVERITY REDUCED
Deploy redundant DNS resolvers — Run at least two independent recursive resolvers (ideally heterogeneous—e.g., BIND + Unbound). Configure clients and stub resolvers with multiple nameserver entries. If one crashes, the other continues serving. This limits the blast radius of a sustained crash loop to intermittent latency rather than full outage.
4
MEDIUM 5.5→MEDIUM 4.5
Enable DNS query rate limiting (RRL) — Configure rate-limit in BIND to throttle high-volume query sources. This raises the cost of sustaining a crash loop, as the attacker must overcome rate limits to repeatedly trigger the sequence. Not a full mitigation—a slow, persistent attacker can still trigger the crash—but buys time for detection.
5
MEDIUM 5.5→MEDIUM 5.0
Monitor for named crash-restart cycles — Set up alerting on systemd journal entries for named assertion failures (INSIST.*failed) and unexpected restarts. A crash loop is the primary exploitation signal. This does not prevent the crash but ensures rapid incident response. Wire to your SIEM or monitoring stack (Prometheus node_exporter, Zabbix, etc.).
What doesn't work
  • WAF / IPS DNS signatures — The attack uses legitimate DNS query packets with standard flags (RD=1 then RD=0). There is no malformed packet or exploit payload for a signature to match. Deep-packet inspection of DNS will not distinguish this from normal query traffic.
  • DNSSEC — DNSSEC validates response authenticity; it has no bearing on server-side assertion failures triggered by query flag combinations. A fully DNSSEC-signed environment is equally vulnerable.
  • Upgrading to DNS-over-HTTPS (DoH) or DNS-over-TLS (DoT) — These encrypt the transport but do not change the server-side RPZ evaluation logic. The same RD=1/RD=0 sequence triggers the same assertion failure over encrypted transports.
04 · Intelligence Metadata

The supporting signals.

In-the-wild exploitationNone confirmed. ISC states no active exploits. Not listed in CISA KEV. No GreyNoise or Shadowserver scanning activity observed as of 2026-10-22.
Proof-of-conceptPrivate PoC only. The ISC GitLab issue #6408 references reporter-provided config and test files that produce a deterministic crash. No public PoC on GitHub, ExploitDB, pocindex.io, or nuclei-templates as of 2026-10-22.
EPSS scoreNot yet scored. CVE disclosed 2026-10-21; FIRST EPSS API returns no data. Expected to be low (<5th percentile) given configuration dependency and DoS-only impact.
KEV statusNot listed. No CISA KEV entry. No federal agency deadline.
CVSS vectorCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H — Network-reachable, no auth, low complexity per spec. The AC:L is technically correct (the crash is deterministic *given* the config) but misleading for prioritization because the config prerequisite effectively raises real-world complexity.
Affected versionsBIND 9.16.0–9.18.50, 9.20.0–9.20.29, 9.21.0–9.21.26, SPE 9.11.3-S1–9.18.50-S1, 9.20.9-S1–9.20.29-S1. Bug introduced in commits 3f81d79ffb / 34dd6521b1, first in tags 9.17.12 and 9.16.14.
Fixed versions9.20.30, 9.21.27, 9.20.30-S1. Debian Trixie: 1:9.20.30-1~deb13u1 (DSA-6576-1). RHEL: RHSA-2026:24339.
Exposure dataCensys/Shodan report ~706K internet-facing BIND recursive resolvers globally (per 2026 scans for related CVEs). However, the subset running RPZ with mixed recursive-only settings is estimated at <5% of that population. Most enterprise resolvers are internal-only behind ACLs.
ResearcherVitaly Simonovich (also credited for CVE-2026-96888). Reported via ISC coordinated disclosure.
Disclosure timelineReserved 2026-09-24. Published 2026-10-21. Patches released same day.

Sources.

  1. ISC Advisory: CVE-2026-97313
  2. ISC GitLab Issue #6408
  3. SecurityOnline: BIND 9 Vulnerabilities October 2026
  4. Debian Security Advisory DSA-6576-1
  5. Red Hat Errata RHSA-2026:24339
  6. BIND 9.21.28-dev Release Notes
  7. Canadian Centre for Cyber Security Advisory AV26-1072
  8. LinuxCompatible: ISC Releases BIND 9.20.30 and 9.21.27
05 · The Call

Final Verdict
↓ DOWNGRADED to MEDIUM (5.5/10)

Why this verdict

  • Configuration gate is the primary friction. The vulnerability requires ≥2 RPZ zones with *mixed* recursive-only settings. RPZ is a minority BIND feature (estimated 30–40% of enterprise BIND deployments). Mixed recursive-only is a deliberate non-default choice within that subset—realistically <5–10% of RPZ users. This compounds to roughly 2–4% of all BIND installations being vulnerable. CVSS cannot encode this; we adjust downward by ~1.5 points.
  • DoS-only impact caps the ceiling. No code execution, no data exfiltration, no privilege escalation. The assertion failure kills named, which systemd restarts in seconds. A sustained outage requires persistent attacker access and knowledge of the triggering QNAME. This is disruptive but recoverable.
  • Role multiplier: DNS recursive resolvers are critical infrastructure, but the outcome does not meet the HIGH floor. Internal DNS resolvers with RPZ are high-value components—an outage disrupts name resolution fleet-wide. However, the blast radius is *service disruption*, not domain takeover, fleet compromise, mass data egress, supply-chain pivot, or OT-safety impact. The HIGH floor requires one of those outcomes. DNS DoS is serious but falls short of the threshold. Additionally, enterprises with redundant DNS (secondary resolvers, stub forwarders, DoH fallback) limit the blast radius further.
  • No exploitation pressure. Zero in-the-wild activity, no public PoC, no KEV listing, EPSS not yet scored but expected low. There is no urgency signal from the threat landscape.
  • Timing window adds real friction. The second RD=0 query must arrive while the async RPZ fetch is still in flight. Network jitter, caching, and resolver load can close this window, making exploitation less reliable than the CVSS AC:L suggests.

Why not higher?

The configuration prerequisite disqualifies this from HIGH. The attack only works against the small subset of BIND servers running ≥2 RPZ zones with mixed recursive-only values—a non-default, unusual setup. The impact is DoS only, with no path to code execution or data compromise. The HIGH floor for critical-infrastructure roles requires outcomes like domain takeover or fleet compromise, which a DNS crash does not produce. No exploitation activity or public PoC exists to create urgency.

Why not lower?

Despite the narrow configuration gate, this is still a remotely-triggerable, unauthenticated crash in a network-critical service. Where the preconditions *are* met, the crash is deterministic and repeatable—an attacker can sustain a DNS outage. BIND is the most widely deployed DNS software, and RPZ-enabled resolvers are typically security-critical chokepoints. A LOW rating would understate the impact for the minority of operators who *are* vulnerable. MEDIUM correctly signals that affected operators should patch within 365 days while the unaffected majority can deprioritize.

06 · Verification

Crowdsourced verification payload.

Run this script on each BIND DNS server host as root or a user with read access to named.conf. Invoke with: sudo bash check_cve_2026_97313.sh or optionally sudo bash check_cve_2026_97313.sh /path/to/named.conf. Exit code 0 = VULNERABLE, 1 = PATCHED, 2 = UNKNOWN.

noisgate-verify.sh
BASHREAD-ONLYSAFE
#!/usr/bin/env bash\n# noisgate: CVE-2026-97313 verification\n# Checks BIND version + RPZ mixed recursive-only config\nset -uo pipefail\n\nCONF=\"${1:-/etc/named.conf}\"\nALT_CONF=\"/etc/bind/named.conf\"\n\nif [[ ! -f \"$CONF\" ]]; then\n  if [[ -f \"$ALT_CONF\" ]]; then\n    CONF=\"$ALT_CONF\"\n  else\n    echo \"UNKNOWN - Cannot locate named.conf at $CONF or $ALT_CONF\"\n    exit 2\n  fi\nfi\n\nNAMED_BIN=$(command -v named 2>/dev/null || true)\nif [[ -z \"$NAMED_BIN\" ]]; then\n  echo \"UNKNOWN - named binary not found in PATH\"\n  exit 2\nfi\n\nVERSION=$(\"$NAMED_BIN\" -v 2>/dev/null | grep -oP '\\d+\\.\\d+\\.\\d+' | head -1)\nif [[ -z \"$VERSION\" ]]; then\n  echo \"UNKNOWN - Could not determine BIND version\"\n  exit 2\nfi\necho \"Detected BIND version: $VERSION\"\n\nIFS='.' read -r MAJOR MINOR PATCH <<< \"$VERSION\"\n\nPATCHED=0\nif [[ \"$MAJOR\" -eq 9 ]]; then\n  if [[ \"$MINOR\" -eq 20 && \"$PATCH\" -ge 30 ]]; then PATCHED=1; fi\n  if [[ \"$MINOR\" -eq 21 && \"$PATCH\" -ge 27 ]]; then PATCHED=1; fi\n  if [[ \"$MINOR\" -gt 21 ]]; then PATCHED=1; fi\nfi\n\nif [[ \"$PATCHED\" -eq 1 ]]; then\n  echo \"PATCHED - BIND $VERSION is not affected by CVE-2026-97313\"\n  exit 1\nfi\n\nVULN_VER=0\nif [[ \"$MAJOR\" -eq 9 ]]; then\n  if [[ \"$MINOR\" -ge 16 && \"$MINOR\" -le 18 ]]; then VULN_VER=1; fi\n  if [[ \"$MINOR\" -eq 20 && \"$PATCH\" -le 29 ]]; then VULN_VER=1; fi\n  if [[ \"$MINOR\" -eq 21 && \"$PATCH\" -le 26 ]]; then VULN_VER=1; fi\nfi\n\nif [[ \"$VULN_VER\" -eq 0 ]]; then\n  echo \"PATCHED - BIND $VERSION is outside the vulnerable range\"\n  exit 1\nfi\n\necho \"Checking RPZ configuration in $CONF...\"\nRPZ_BLOCK=$(grep -A 200 'response-policy' \"$CONF\" 2>/dev/null | head -200 || true)\n\nif [[ -z \"$RPZ_BLOCK\" ]]; then\n  echo \"PATCHED - No response-policy (RPZ) found; CVE-2026-97313 not exploitable\"\n  exit 1\nfi\n\nZONE_COUNT=$(echo \"$RPZ_BLOCK\" | grep -c 'zone' 2>/dev/null || echo \"0\")\nif [[ \"$ZONE_COUNT\" -lt 2 ]]; then\n  echo \"PATCHED - Fewer than 2 RPZ zones; CVE-2026-97313 requires at least 2\"\n  exit 1\nfi\n\nHAS_REC_NO=$(echo \"$RPZ_BLOCK\" | grep -ci 'recursive-only no' 2>/dev/null || echo \"0\")\nif [[ \"$HAS_REC_NO\" -gt 0 && \"$ZONE_COUNT\" -ge 2 ]]; then\n  echo \"VULNERABLE - BIND $VERSION with mixed RPZ recursive-only settings\"\n  echo \"  RPZ zones: $ZONE_COUNT, zones with recursive-only no: $HAS_REC_NO\"\n  exit 0\nelse\n  echo \"PATCHED - RPZ zones found but no mixed recursive-only settings\"\n  exit 1\nfi