CVE-2026-58042
This Vulnerability has been fixed in the Never-Ending Support (NES) version offered by HeroDevs.
Overview
Node.js is a JavaScript runtime built on the V8 JavaScript engine. It uses an event-driven, non-blocking I/O model that makes it lightweight and efficient, and it is widely used to build scalable server-side and networking applications.
A denial of service vulnerability (CVE-2026-58042) has been identified in the Node.js DNS resolver, where dns.resolveAny() aborts the Node.js process when a DNS response contains more than 256 A records. Repeated triggering of this condition can lead to denial of service against the affected application.
Per MITRE, CWE-400, Uncontrolled Resource Consumption, describes a product that "does not properly control the allocation and maintenance of a limited resource." The limited resource here is a fixed-size buffer the resolver reserves for per-record time-to-live values.
This issue affects all users on the active 26.x, 24.x, and 22.x release lines below the patched versions. The End-of-Life 12.x, 14.x, 16.x, 18.x, and 20.x lines are affected as well and received a post-EOL security fix under Node.js NES. The issue is tracked in GitHub Security Advisory GHSA-pgf6-87r4-94vm.
Details
Module Info
- Product: Node.js
- Affected packages: nodejs/node (the Node.js runtime itself)
- Affected versions:
- <=26.5.0
- <=24.18.0
- <=22.23.1
- GitHub repository: https://github.com/nodejs/node
- Published packages: https://github.com/nodejs/node/releases
- GitHub Security Advisory: GHSA-pgf6-87r4-94vm
- Package manager: n/a (Node.js ships as a runtime distribution rather than a registry package)
- Fixed in: Node.js NES v12.22.20, v14.21.13, v16.20.14, v18.20.19, and v20.20.4. The 14.x, 16.x, 18.x, and 20.x NES releases shipped on August 3, 2026; the 12.x NES release shipped on August 11, 2026.
Vulnerability Info
This Medium-severity vulnerability is found in the DNS resolver of the Node.js runtime, in the C++ source file src/cares_wrap.cc, in every release below the patched version of each line.
Node.js resolves DNS queries through the bundled c-ares library. When an application calls dns.resolveAny(), Node.js asks c-ares to parse the reply and hand back both the addresses and their time-to-live values. The caller has to supply the buffer that receives those TTL entries along with its capacity, and c-ares fills it up to that capacity.
In affected versions the resolver declared that buffer as a fixed 256-entry array on the stack, ares_addrttl addrttls[256], and passed its size as the capacity. A reply carrying more A records than the buffer can hold exceeds what the code is prepared to handle and the process aborts. The abort is the whole impact: a crash rather than memory disclosure or corruption, which is why the CVSS vector records availability impact only with no confidentiality or integrity impact.
An attacker needs to be able to make the application resolve a name whose reply they control, which is what the high attack complexity in the vector reflects. Once that is possible the crash can be repeated, and a process that aborts on demand is a denial of service.
The upstream fix (commit 3e6cca0e6a, "dns: handle large resolveAny address replies", landed through public pull request nodejs/node#64820) replaces the fixed array with a heap-allocated vector sized from the answer count in the DNS reply header:
int GetAnswerCountForTTLBuffer(const unsigned char* buf, int len) {
static constexpr int kDNSAnswerCountOffset = 6;
static constexpr int kAresDefaultTTLBufferLength = 256;
if (len <= kDNSAnswerCountOffset + 1) {
return kAresDefaultTTLBufferLength;
}
const int answer_count = (static_cast<int>(buf[kDNSAnswerCountOffset]) << 8) |
static_cast<int>(buf[kDNSAnswerCountOffset + 1]);
return answer_count == 0 ? 1 : answer_count;
}
The buffer is now large enough for whatever the reply declares, falling back to the old 256 entries when the header is too short to read and to a single entry when the reply declares no answers.
Note: The advisory names dns.resolveAny(), and that is the path the upstream regression test exercises. The same fixed 256-entry pattern also appeared in the A and AAAA query paths and the fix changes all three, so applications that call dns.resolve4() or dns.resolve6() receive the same hardening. Upstream did not state those paths as affected, so this doc does not claim they were.
Mitigation
The Node.js 12.x, 14.x, 16.x, 18.x, and 20.x release lines are End-of-Life and will not receive an upstream fix for this issue. For more information see here.
Users of the affected components should apply one of the following mitigations:
- Upgrade to a currently supported Node.js release line at or above the patched version (22.23.2, 24.18.1, or 26.5.1).
- Migrate affected applications away from the End-of-Life Node.js release lines.
- Leverage a commercial support partner like HeroDevs for post-EOL security support (Node.js NES).
Credits
- cantina-security (reporter)
- RafaelGSS (remediation developer)