CVE-2026-77860: 'serve-expired' can bypass Unbound 'wait-limit'
In NLnetLabs Unbound 1.20.0 up to and including 1.26.0, a vulnerability on the 'serve-expired' code path can cause a double decrement on the 'wait-limit' counter per client IP essentially bypassing one of the counter measures that was introduced for DNSBomb (CVE-2024-33655). A malicious actor can exploit this by controlling an authoritative zone with short TTL, so cached entries expire quickly. Each 'slow' query, one the attacker's authoritative never answers, is followed by one query for an expired cached name, which is answered immediately via the 'serve-expired' path and decrements the counter twice. This second query was named 'pump'. By alternating slow queries and pumps, the attacker keeps the per-client counter at or below the configured 'wait-limit' indefinitely, and can hold an arbitrary number of pending queries from a single source IP, up to the global mesh quota (num-queries-per-thread); eventually bypassing one of the counter measures introduced for DNSBomb (CVE-2024-33655). This vulnerability is present on the 'serve-expired' code path.
Affected Software
Remediation
Recommended actions to resolve this vulnerability, in priority order.
- Upgrade
Upgrade
NLnetLabs Unboundto a version that resolves this vulnerability.Fixed in 1.26.1
Event History
Frequently Asked Questions
What must an attacker control to exploit this issue?
The attacker must control an authoritative zone with a short TTL so that cached names expire quickly. Their authoritative server must leave selected queries unanswered to create pending “slow” queries, while they issue queries for expired cached names as pumps.
What resource limit still constrains the attack?
The attacker can keep the per-client wait-limit counter at or below its configured limit, allowing pending queries from one source IP to accumulate. The number of pending queries is still bounded by the global mesh quota, num-queries-per-thread.
Which Unbound deployments are in scope?
The issue affects NLnetLabs Unbound versions 1.20.0 through 1.26.0, inclusive, on the serve-expired code path.