CVE-2023-5363
Patch Available.
This Vulnerability has been fixed in the Never-Ending Support (NES) version offered by HeroDevs.
Overview
Node.js is a JavaScript runtime built on Chrome's V8 JavaScript engine. It uses an event-driven, non-blocking I/O model and is widely used for web applications and server-side development. Node.js compiles its own copy of OpenSSL from deps/openssl in the Node.js source tree and statically links it into the runtime, so a flaw in the bundled OpenSSL is present in every Node.js binary built from that tree. Node.js 17.x was the first release line to bundle OpenSSL 3.0.
A vulnerability (CVE-2023-5363) has been identified in the OpenSSL 3.0 library bundled with Node.js. When a cipher is initialized with EVP_EncryptInit_ex2(), EVP_DecryptInit_ex2() or EVP_CipherInit_ex2() and the key length or IV length is changed through the parameter array passed to that call, OpenSSL applies the change only after the key and IV have already been set up. The key or IV can then be truncated or over-read, and a truncated IV in GCM, CCM or OCB mode can lead to IV reuse and a loss of confidentiality.
This flaw maps to CWE-684 (Incorrect Provision of Specified Functionality), where code does not behave as its documented interface says it will. OpenSSL 3.0's _ex2 initialization functions accept an OSSL_PARAM array that is meant to configure the cipher, including "keylen" and "ivlen", before it is used. Internally, those parameters were processed at the end of initialization, after the key and IV had been copied in using the old lengths.
The affected ciphers and modes are RC2, RC4, RC5, CCM, GCM and OCB. The most serious case is AES-GCM with a deterministic IV built as NIST SP 800-38D section 8.2.1 describes, where truncating the counter part of the IV can make IVs repeat and so break confidentiality. OpenSSL expected very few applications to be vulnerable, because changing key or IV lengths this way is uncommon, the _ex2 API was new, and mismatched results would normally show up in testing. OpenSSL's TLS implementation and its FIPS providers are not affected. Node.js's built-in crypto module initializes ciphers with the older EVP_CipherInit_ex() and sets the IV and key lengths before supplying the key and IV, so exposure in a Node.js deployment depends on native addons or embedders that use the _ex2 functions through the bundled OpenSSL. This issue affects the Node.js 17.x through 21.x release lines up to the versions listed above.
Details
Module Info
- Product: Node.js
- Affected packages: node (bundles OpenSSL 3.0 under deps/openssl)
- Affected versions: >=17.0.0 <=17.9.1 >=18.0.0 <18.19.0 >=19.0.0 <=19.9.0 >=20.0.0 <20.10.0 >=21.0.0 <21.2.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 21.2.0 (November 14, 2023), 20.10.0 (November 22, 2023) and 18.19.0 (November 29, 2023), which upgraded the bundled OpenSSL to 3.0.12; this CVE is also listed in the Node.js NES v16.20.3 release notes (16.x line, shipped July 30, 2024). Node.js 17.x and 19.x never received a fix
Vulnerability Info
This High-severity vulnerability is found in OpenSSL 3.0.0 through 3.0.11 (and 3.1.0 through 3.1.3), the versions bundled by Node.js 17.x through 21.x before the releases listed above. NVD assigns a CVSS v3.1 score of 7.5; OpenSSL rates the issue Moderate overall, explaining that it is unlikely to affect many applications but very serious for those it does.
A caller that needs a non-default key or IV length, such as a 96-bit counter-based GCM IV of a different size, can pass "keylen" or "ivlen" in the OSSL_PARAM array to the _ex2 initialization call along with the key and IV. In the vulnerable versions, evp_cipher_init_internal() installed the key and IV first, using the cipher's existing lengths, and only then applied the parameter array, so the new lengths never governed how the key and IV were read. A shorter length than the default led to over-reading; a longer one led to truncation. The fix processes the key length and IV length parameters at the start of initialization, before the key and IV are set. See the OpenSSL 3.0 fix commit for the exact change.
The flaw is not triggered by an attacker's input; it is a misbehavior in applications that use this API pattern. Where it applies, an attacker who observes the ciphertext can exploit repeated IVs in GCM, CCM or OCB to recover information about the plaintext or forge messages. Truncated or over-read keys, and over-read IVs, produce incorrect results and could in some cases cause a memory access fault.
Note: Node.js applications that use only the built-in crypto, tls and https modules are not exposed by this issue, and OpenSSL 1.1.1 and older do not have the _ex2 functions, so Node.js 16.x and earlier are not affected.
Mitigation
Users of the affected components should apply one of the following mitigations:
- Upgrade to a currently supported Node.js LTS release (22.x or 24.x), both of which bundle OpenSSL 3.5, which includes 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
- Tony Battersby from Cybernetics (finder)
- Dr Paul Dale from the OpenSSL project (remediation developer)