bind/bind-9.18-CVE-2026-1519-test.patch
Petr Menšík d598399af2 [9.18] [CVE-2026-1519] sec: usr: Fix unbounded NSEC3 iterations when validating referrals to unsigned delegations
DNSSEC-signed zones may contain high iteration-count NSEC3 records,
which prove that certain delegations are insecure. Previously, a
validating resolver encountering such a delegation processed these
iterations up to the number given, which could be a maximum of 65,535.
This has been addressed by introducing a processing limit, set at 150.
Now, if such an NSEC3 record is encountered, the delegation will be
treated as insecure.

ISC would like to thank Samy Medjahed/Ap4sh for bringing this
vulnerability to our attention.

Closes isc-projects/bind9#5708

Resolves-Vulnerability: CVE-2026-1519
2026-04-17 13:01:19 +02:00

338 lines
11 KiB
Diff

From 7df00188c93d1fb8496328976e00192dd657d5aa Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Nicki=20K=C5=99=C3=AD=C5=BEek?= <nicki@isc.org>
Date: Tue, 3 Feb 2026 18:25:04 +0100
Subject: [PATCH] Reproducer for CVE-2026-1519
When a validating resolver processes a delegation from a DNSSEC-signed
zone which uses too many NSEC3 iterations, it should cease the attempt
to validate due to an NSEC3 iteration limit being exceeded and fall back
to insecure.
(cherry picked from commit 9bc14a89f1313aa38330e84674ac3b7691db3383)
(cherry picked from commit 2c82f99a3c95f356861d5977f12ef9bbe2063cb6)
---
.../system/nsec3-delegation/ns1/named.conf.j2 | 35 +++++++++++
bin/tests/system/nsec3-delegation/ns1/root.db | 25 ++++++++
.../ns2/iter-too-many.db.j2.manual | 31 ++++++++++
.../system/nsec3-delegation/ns2/named.conf.j2 | 40 ++++++++++++
.../nsec3-delegation/ns2/sub.iter-too-many.db | 24 ++++++++
.../system/nsec3-delegation/ns3/named.conf.j2 | 37 +++++++++++
.../nsec3-delegation/ns3/trusted.conf.j2 | 1 +
.../tests_excessive_nsec3_iterations.py | 61 +++++++++++++++++++
8 files changed, 254 insertions(+)
create mode 100644 bin/tests/system/nsec3-delegation/ns1/named.conf.j2
create mode 100644 bin/tests/system/nsec3-delegation/ns1/root.db
create mode 100644 bin/tests/system/nsec3-delegation/ns2/iter-too-many.db.j2.manual
create mode 100644 bin/tests/system/nsec3-delegation/ns2/named.conf.j2
create mode 100644 bin/tests/system/nsec3-delegation/ns2/sub.iter-too-many.db
create mode 100644 bin/tests/system/nsec3-delegation/ns3/named.conf.j2
create mode 120000 bin/tests/system/nsec3-delegation/ns3/trusted.conf.j2
create mode 100644 bin/tests/system/nsec3-delegation/tests_excessive_nsec3_iterations.py
diff --git a/bin/tests/system/nsec3-delegation/ns1/named.conf.j2 b/bin/tests/system/nsec3-delegation/ns1/named.conf.j2
new file mode 100644
index 0000000000..65016d1c67
--- /dev/null
+++ b/bin/tests/system/nsec3-delegation/ns1/named.conf.j2
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * SPDX-License-Identifier: MPL-2.0
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, you can obtain one at https://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+options {
+ query-source address 10.53.0.1;
+ notify-source 10.53.0.1;
+ transfer-source 10.53.0.1;
+ port @PORT@;
+ pid-file "named.pid";
+ listen-on { 10.53.0.1; };
+ listen-on-v6 { none; };
+ recursion no;
+ dnssec-validation no;
+};
+
+controls {
+ inet 10.53.0.1 port @CONTROLPORT@ allow { any; } keys { rndc_key; };
+};
+
+include "../../_common/rndc.key";
+
+zone "." {
+ type primary;
+ file "root.db";
+};
diff --git a/bin/tests/system/nsec3-delegation/ns1/root.db b/bin/tests/system/nsec3-delegation/ns1/root.db
new file mode 100644
index 0000000000..c3f80d0d4b
--- /dev/null
+++ b/bin/tests/system/nsec3-delegation/ns1/root.db
@@ -0,0 +1,25 @@
+; Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+;
+; SPDX-License-Identifier: MPL-2.0
+;
+; This Source Code Form is subject to the terms of the Mozilla Public
+; License, v. 2.0. If a copy of the MPL was not distributed with this
+; file, you can obtain one at https://mozilla.org/MPL/2.0/.
+;
+; See the COPYRIGHT file distributed with this work for additional
+; information regarding copyright ownership.
+
+$TTL 300
+. IN SOA . . (
+ 2025063000 ; serial
+ 600 ; refresh
+ 600 ; retry
+ 1200 ; expire
+ 600 ; minimum
+ )
+. NS a.root-servers.nil.
+
+a.root-servers.nil A 10.53.0.1
+
+iter-too-many. NS ns2.iter-too-many.
+ns2.iter-too-many. A 10.53.0.2
diff --git a/bin/tests/system/nsec3-delegation/ns2/iter-too-many.db.j2.manual b/bin/tests/system/nsec3-delegation/ns2/iter-too-many.db.j2.manual
new file mode 100644
index 0000000000..fa5023d21b
--- /dev/null
+++ b/bin/tests/system/nsec3-delegation/ns2/iter-too-many.db.j2.manual
@@ -0,0 +1,31 @@
+; Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+;
+; SPDX-License-Identifier: MPL-2.0
+;
+; This Source Code Form is subject to the terms of the Mozilla Public
+; License, v. 2.0. If a copy of the MPL was not distributed with this
+; file, you can obtain one at https://mozilla.org/MPL/2.0/.
+;
+; See the COPYRIGHT file distributed with this work for additional
+; information regarding copyright ownership.
+
+{% raw %}
+$TTL 300
+@ IN SOA ns2.iter-too-many. hostmaster.iter-too-many. (
+ 2026020300 ; serial
+ 20 ; refresh (20 seconds)
+ 20 ; retry (20 seconds)
+ 1814400 ; expire (3 weeks)
+ 3600 ; minimum (1 hour)
+)
+
+@ IN NS ns2.iter-too-many.
+ns2 IN A 10.53.0.2
+
+sub IN NS ns2.sub.iter-too-many.
+ns2.sub IN A 10.53.0.2
+{% endraw %}
+
+{% for dnskey in dnskeys %}
+@dnskey@
+{% endfor %}
diff --git a/bin/tests/system/nsec3-delegation/ns2/named.conf.j2 b/bin/tests/system/nsec3-delegation/ns2/named.conf.j2
new file mode 100644
index 0000000000..2f4823574f
--- /dev/null
+++ b/bin/tests/system/nsec3-delegation/ns2/named.conf.j2
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * SPDX-License-Identifier: MPL-2.0
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, you can obtain one at https://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+options {
+ query-source address 10.53.0.2;
+ notify-source 10.53.0.2;
+ transfer-source 10.53.0.2;
+ port @PORT@;
+ pid-file "named.pid";
+ listen-on { 10.53.0.2; };
+ listen-on-v6 { none; };
+ recursion no;
+ dnssec-validation no;
+};
+
+controls {
+ inet 10.53.0.2 port @CONTROLPORT@ allow { any; } keys { rndc_key; };
+};
+
+include "../../_common/rndc.key";
+
+zone "iter-too-many" {
+ type primary;
+ file "iter-too-many.signed.db";
+};
+
+zone "sub.iter-too-many" {
+ type primary;
+ file "sub.iter-too-many.db";
+};
diff --git a/bin/tests/system/nsec3-delegation/ns2/sub.iter-too-many.db b/bin/tests/system/nsec3-delegation/ns2/sub.iter-too-many.db
new file mode 100644
index 0000000000..09b2bb6fb3
--- /dev/null
+++ b/bin/tests/system/nsec3-delegation/ns2/sub.iter-too-many.db
@@ -0,0 +1,24 @@
+; Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+;
+; SPDX-License-Identifier: MPL-2.0
+;
+; This Source Code Form is subject to the terms of the Mozilla Public
+; License, v. 2.0. If a copy of the MPL was not distributed with this
+; file, you can obtain one at https://mozilla.org/MPL/2.0/.
+;
+; See the COPYRIGHT file distributed with this work for additional
+; information regarding copyright ownership.
+
+$TTL 300
+@ IN SOA ns2.sub.iter-too-many. hostmaster.sub.iter-too-many. (
+ 2026020300 ; serial
+ 20 ; refresh (20 seconds)
+ 20 ; retry (20 seconds)
+ 1814400 ; expire (3 weeks)
+ 3600 ; minimum (1 hour)
+)
+
+@ IN NS ns2.sub.iter-too-many.
+ns2 IN A 10.53.0.2
+
+example IN A 127.0.0.1
diff --git a/bin/tests/system/nsec3-delegation/ns3/named.conf.j2 b/bin/tests/system/nsec3-delegation/ns3/named.conf.j2
new file mode 100644
index 0000000000..e36b88c53e
--- /dev/null
+++ b/bin/tests/system/nsec3-delegation/ns3/named.conf.j2
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * SPDX-License-Identifier: MPL-2.0
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, you can obtain one at https://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+options {
+ query-source address 10.53.0.3;
+ notify-source 10.53.0.3;
+ transfer-source 10.53.0.3;
+ port @PORT@;
+ pid-file "named.pid";
+ listen-on { 10.53.0.3; };
+ listen-on-v6 { none; };
+ recursion yes;
+ dnssec-validation yes;
+};
+
+controls {
+ inet 10.53.0.3 port @CONTROLPORT@ allow { any; } keys { rndc_key; };
+};
+
+include "../../_common/rndc.key";
+
+zone "." {
+ type hint;
+ file "../../_common/root.hint";
+};
+
+include "trusted.conf";
diff --git a/bin/tests/system/nsec3-delegation/ns3/trusted.conf.j2 b/bin/tests/system/nsec3-delegation/ns3/trusted.conf.j2
new file mode 120000
index 0000000000..cb0be77b22
--- /dev/null
+++ b/bin/tests/system/nsec3-delegation/ns3/trusted.conf.j2
@@ -0,0 +1 @@
+../../_common/trusted.conf.j2
\ No newline at end of file
diff --git a/bin/tests/system/nsec3-delegation/tests_excessive_nsec3_iterations.py b/bin/tests/system/nsec3-delegation/tests_excessive_nsec3_iterations.py
new file mode 100644
index 0000000000..f85384bb1e
--- /dev/null
+++ b/bin/tests/system/nsec3-delegation/tests_excessive_nsec3_iterations.py
@@ -0,0 +1,61 @@
+# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+#
+# SPDX-License-Identifier: MPL-2.0
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, you can obtain one at https://mozilla.org/MPL/2.0/.
+#
+# See the COPYRIGHT file distributed with this work for additional
+# information regarding copyright ownership.
+
+from isctest.run import EnvCmd
+
+import isctest
+
+
+def bootstrap():
+ templates = isctest.template.TemplateEngine(".")
+ keygen = EnvCmd("KEYGEN", "-a ECDSA256")
+ signer = EnvCmd("SIGNER")
+
+ isctest.log.info("setup iter-too-many.")
+ zonename = "iter-too-many."
+ ksk_name = keygen(f"-f KSK {zonename}", cwd="ns2").out.strip()
+ zsk_name = keygen(f"{zonename}", cwd="ns2").out.strip()
+ ksk = isctest.kasp.Key(ksk_name, keydir="ns2")
+ zsk = isctest.kasp.Key(zsk_name, keydir="ns2")
+ dnskeys = [ksk.dnskey, zsk.dnskey]
+
+ tdata = {
+ "dnskeys": dnskeys,
+ }
+ templates.render(f"ns2/{zonename}db", tdata, template=f"ns2/{zonename}db.j2.manual")
+ signer(
+ f"-P -o {zonename} -f {zonename}signed.db -3 A1B2C3D4 -H too-many -H 151 -S {zonename}db",
+ cwd="ns2",
+ )
+
+ return {
+ "trust_anchors": [
+ ksk.into_ta("static-key"),
+ ],
+ }
+
+
+def test_excessive_nsec3_iterations_delegation(ns3):
+ # reproducer for CVE-2026-1519 [GL#5708]
+ zone = "example.sub.iter-too-many"
+ msg = isctest.query.create(zone, "A")
+ res = isctest.query.tcp(msg, ns3.ip)
+
+ # an insecure response is expected regardless of the NSEC3 iteration limit,
+ # because the sub.iter-too-many. zone is unsigned. the real difference is
+ # in the CPU usage required for generating such response, but that can't be
+ # easily and reliably tested in an automated fashion
+ isctest.check.noerror(res)
+
+ with ns3.watch_log_from_start() as watcher:
+ watcher.wait_for_line(
+ f"validating {zone}/A: validator_callback_ds: too many iterations"
+ )
--
2.53.0