Check that an NSEC signer is at or above the name to be validated

Add a check that an NSEC record being used as a proof of nonexistence
for a given name is not signed by a name lower in the DNS hierarchy than
the one in question.

Fixes: isc-projects/bind9#5876

(cherry picked from commit c5f99f3508)
This commit is contained in:
Evan Hunt 2026-05-22 21:04:03 -07:00
parent 93aa52442a
commit d3c85737f7
3 changed files with 22 additions and 0 deletions

View file

@ -441,10 +441,23 @@ dns_nsec_noexistnodata(dns_rdatatype_t type, const dns_name_t *name,
return DNS_R_DNAME;
}
if (relation != dns_namereln_subdomain &&
dns_nsec_typepresent(&rdata, dns_rdatatype_soa))
{
/*
* An NSEC with an SOA in the bitmap can only cover
* names that are subdomains of the owner.
*/
(*logit)(arg, ISC_LOG_DEBUG(3),
"ignoring nsec with SOA covering non-subdomain");
return ISC_R_IGNORE;
}
result = dns_rdata_tostruct(&rdata, &nsec, NULL);
if (result != ISC_R_SUCCESS) {
return result;
}
relation = dns_name_fullcompare(&nsec.next, name, &order, &nlabels);
if (order == 0) {
dns_rdata_freestruct(&nsec);

View file

@ -846,6 +846,8 @@ validator_callback_nsec(void *arg) {
rdataset->trust == dns_trust_secure &&
(NEEDNODATA(val) || NEEDNOQNAME(val)) &&
!FOUNDNODATA(val) && !FOUNDNOQNAME(val) &&
dns_name_issubdomain(val->name,
&subvalidator->siginfo->signer) &&
dns_nsec_noexistnodata(val->type, val->name,
subvalidator->name, rdataset,
&exists, &data, wild, validator_log,

View file

@ -9959,6 +9959,13 @@ query_coveringnsec(query_ctx_t *qctx) {
goto cleanup;
}
/*
* The query name can't be above the signer of the NSEC.
*/
if (!dns_name_issubdomain(qctx->client->query.qname, signer)) {
goto cleanup;
}
/*
* If NSEC or RRSIG are missing from the type map
* reject the NSEC RRset.