CVE-2024-9143
Patch Available.
This Vulnerability has been fixed in the Never-Ending Support (NES) version offered by HeroDevs.
Overview
Node.js is an asynchronous, event-driven JavaScript runtime designed for building scalable network applications. The official Node.js distributions do not link against a system cryptography library: they compile and ship their own copy of OpenSSL at deps/openssl in the Node.js source tree, and the built-in crypto and tls modules are bindings over that bundled copy. A vulnerability in the bundled OpenSSL therefore affects Node.js directly, whether or not Node.js itself contains any new code.
An out-of-bounds memory access vulnerability (CVE-2024-9143) has been identified in the OpenSSL library bundled with Node.js. OpenSSL's low-level APIs for elliptic curves over binary fields, GF(2^m), accept explicit curve parameters, including the field polynomial. The polynomial is required to have a non-zero constant term. However, OpenSSL did not reject polynomials that break this rule, and processing one leads to reads and writes outside the bounds of an internal array. The result can be a crash, and OpenSSL says remote code execution cannot easily be ruled out.
This behaviour maps to CWE-125 (Out-of-bounds Read) and CWE-787 (Out-of-bounds Write), where software reads or writes data past the end, or before the beginning, of the buffer it intends to use. In OpenSSL, converting the invalid polynomial into its array form produces a result that the binary-field arithmetic then indexes past its end. Out-of-bounds writes of this kind can corrupt memory, while out-of-bounds reads typically end in a crash.
Exploitation requires an application that builds a binary curve from untrusted explicit parameters, through EC_GROUP_new_curve_GF2m(), EC_GROUP_new_from_params() or similar low-level OpenSSL APIs. OpenSSL notes that the encodings used by real protocols, including the X9.62 encoding used for EC keys in X.509 certificates, cannot represent the problematic values, so only "exotic" curve encodings could reach the bug. Node.js's own crypto code does not call these APIs directly. The likelihood of a vulnerable Node.js application is therefore low. This issue affects every Node.js release line up to 17.x, 19.x and 21.x, and 18.x, 20.x, 22.x and 23.x before the versions listed above.
Details
Module Info
- Product: Node.js
- Affected packages: node (bundles OpenSSL under deps/openssl)
- Affected versions: <=17.9.1 >=18.0.0 <18.20.8 >=19.0.0 <=19.9.0 >=20.0.0 <20.19.5 >=21.0.0 <=21.7.3 >=22.0.0 <22.15.0 >=23.0.0 <23.10.0
- GitHub repository: https://github.com/nodejs/node
- Published packages: https://nodejs.org/en/download
- Package manager: Not applicable; Node.js is distributed as runtime builds from nodejs.org rather than as a published npm package
- Fixed in: Node.js 23.10.0 (March 13, 2025), 18.20.8 (March 27, 2025), 22.15.0 (April 23, 2025) and 20.19.5 (September 3, 2025), upstream releases whose bundled OpenSSL includes the fix; Node.js NES v18.20.13 (NES 18.x line, shipped August 27, 2025), which updated OpenSSL to 3.0.16; Node.js 24.0.0 and later are not affected
Vulnerability Info
This Medium-severity vulnerability is found in the binary-field (GF(2^m)) elliptic curve code of the OpenSSL library that Node.js bundles at deps/openssl, in every Node.js release whose bundled OpenSSL predates 3.0.16 or lacks the equivalent backport. The CISA ADP assigns a CVSS v3.1 score of 4.3; NVD has not published its own score.
Binary-field arithmetic in OpenSSL represents the field polynomial as an array of exponents, built by BN_GF2m_poly2arr(). The arithmetic routines that consume that array assume the polynomial's constant term is 1. In the vulnerable implementation, BN_GF2m_poly2arr() accepted any non-zero polynomial, including one whose constant term is zero. The array it produced then led BN_GF2m_mod_arr() and related functions to read and write outside the array. The fix rejects any polynomial that is not odd, which is the condition for a non-zero constant term. It also rejects polynomials whose degree exceeds OpenSSL's maximum supported field size. See the OpenSSL 3.0 fix commit for the exact change.
An attacker would need to supply explicit binary-curve parameters to an application that passes them to OpenSSL's low-level curve-construction APIs, using an encoding that can express an invalid field polynomial.
Note: Because X.509 certificates and the standard key formats use the X9.62 encoding, which cannot represent the problematic values, applications that only handle certificates and standard EC keys are not exposed by this issue.
Mitigation
Node.js 23.x reached End-of-Life on June 1, 2025, so the fix in 23.10.0 is the last for that line. Node.js 22.x is still supported and is fixed in 22.15.0 and later. All other affected Node.js release lines are past their support window and will not receive further upstream updates. Node.js 12.x reached End-of-Life on April 30, 2022; Node.js 14.x on April 30, 2023; Node.js 16.x on September 11, 2023; Node.js 17.x on June 1, 2022; Node.js 18.x on April 30, 2025; Node.js 19.x on June 1, 2023; Node.js 20.x on April 30, 2026; and Node.js 21.x on June 1, 2024. For more information see here.
Users of the affected components should apply one of the following mitigations:
- Upgrade to Node.js 22.15.0 or later on the 22.x line, or to Node.js 24.x, both of which include this fix.
- 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, through Node.js NES.
Credits
- Google OSS-Fuzz-Gen (finder)
- Viktor Dukhovni (remediation developer)