[CVE-2023-50868] Preparing an NSEC3 closest encloser proof can exhaust CPU resources
Quick Links | |
---|---|
Incident Manager: | @pspacek |
Deputy Incident Manager: | @ebf |
Public Disclosure Date: | 2024-02-13 |
CVSS Score: | 7.5 |
Security Advisory: | isc-private/printing-press!93 |
Mattermost Channel: | CVE-2023-50868: NSEC3 closest encloser proof can exhaust CPU |
Support Ticket: | N/A |
Release Checklist: | #4555 (closed) |
Earlier Than T-5
-
🔗 (IM) Pick a Deputy Incident Manager -
🚫 🔗 (IM) Respond to the bug reporter - found internally by @pspacek -
🔗 (SwEng) Ensure there are no public merge requests which inadvertently disclose the issue -
🔗 (IM) Assign a CVE identifier -
🔗 (SwEng) Update this issue with the assigned CVE identifier and the CVSS score -
🔗 (SwEng) Determine the range of product versions affected (including the Subscription Edition) -
🔗 (SwEng) Determine whether workarounds for the problem exist -
🔗 (SwEng)⚠ Coordinate with other parties⚠ -
🔗 (Support)Prepare "earliest" notification text and hand it off to Marketing -
🔗 (Marketing)Update "earliest" notification document in SF portal and send bulk email to earliest customers -
🔗 (Support) Create a merge request for the Security Advisory and include all readily available information in it -
🔗 (SwEng)Prepare a private merge request containing a system test reproducing the problem -
🔗 (SwEng)Notify Support when a reproducer is ready -
🔗 (SwEng) Prepare a detailed explanation of the code flow triggering the problem -
🔗 (SwEng)Prepare a private merge request with the fix -
🔗 (SwEng)Ensure the merge request with the fix is reviewed and has no outstanding discussions -
🔗 (Support)Review the documentation changes introduced by the merge request with the fix -
🔗 (SwEng)Prepare backports of the merge request addressing the problem for all affected (and still maintained) branches of a given product -
🔗 (Support) Finish preparing the Security Advisory -
🔗 (QA) Create (or update) the private issue containing links to fixes & reproducers for all CVEs fixed in a given release cycle -
🔗 (QA) (BIND 9 only) Reserve a block ofCHANGES
placeholders once the complete set of vulnerabilities fixed in a given release cycle is determined -
🔗 (QA)Merge the CVE fixes in CVE identifier order -
🔗 (QA)Prepare a standalone patch for the last stable release of each affected (and still maintained) product branch -
🔗 (QA) Prepare ASN releases (as outlined in the Release Checklist)
At T-5
-
🔗 (Marketing) Update the text on the T-5 (from the Printing Press project) and "earliest" ASN documents in the SF portal -
🔗 (Marketing) (BIND 9 only) Update the BIND -S information document in SF with download links to the new versions -
🔗 (Marketing) Bulk email eligible customers to check the SF portal -
🔗 (Marketing) (BIND 9 only) Send a pre-announcement email to the bind-announce mailing list to alert users that the upcoming release will include security fixes
At T-1
-
🔗 (First IM) Send notifications to OS packagers
On the Day of Public Disclosure
-
🔗 (IM) Grant QA & Marketing clearance to proceed with public release -
🔗 (QA/Marketing) Publish the releases (as outlined in the release checklist) -
🔗 (Support) (BIND 9 only) Add the new CVEs to the vulnerability matrix in the Knowledge Base -
🔗 (Support) Bump Document Version for the Security Advisory and publish it in the Knowledge Base -
🔗 (First IM) Send notification emails to third parties -
🔗 (First IM)Advise MITRE about the disclosed CVEs -
🔗 (First IM) Merge the Security Advisory merge request -
🔗 (IM) Inform original reporter (if external) that the security disclosure process is complete -
🔗 (Marketing) Update the SF portal to clear the ASN -
🔗 (Marketing) Email ASN recipients that the embargo is lifted
After Public Disclosure
-
🔗 (QA)Merge a regression test reproducing the bug into all affected (and still maintained) branches
Reproducer
- Sign an empty zone with NSEC3, 150 iterations, and same NSEC3 salt for a good measure:
- local.testiscorg.ch.zone
- Klocal.testiscorg.ch.+014+01043.key
- Klocal.testiscorg.ch.+014+01043.private
dnssec-signzone -u -3 0122345678912345 -H 150 -e 20380101000000 -S -o local.testiscorg.ch -O full -z local.testiscorg.ch.zone Klocal.testiscorg.ch.+014+01043
-
👉🏻 local.testiscorg.ch.zone.signed
- Run an auth with the zone:
- auth.conf
named -g -c auth.conf
- Run a resolver with the zone:
- resolver.conf
named -g -c resolver.conf
- Run attack using dnsperf:
- randlabels.py
python randlabels.py | dnsperf -s 127.0.0.1 -S1
Observed behavior
Around 200 QPS, one CPU maxed out. Tweaking dnsperf params can max out all CPUs with ~ 200 queries per core.
Problem
For NSEC3 we have to hash all the labels between QNAME and zone name to find out a matching NSEC3 RR in authority section. This inflates number of hashes to potentially ~ 127 labels * <NSEC3 iterations> * <number of NSEC3 RRs in the message>
.
We have to cap this somehow. Coordination with other vendors is needed because BIND, Unbound, Knot Resolver, and PowerDNS in current versions are affected. This seems like a protocol issue so other vendors are most likely also affected, see the NSEC3 algorithm here: https://datatracker.ietf.org/doc/html/rfc5155#section-8.3