CVE-2022-2097
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 the built-in crypto module, including crypto.createCipheriv(), sits on top of that bundled copy. Node.js publishes official 32-bit x86 builds for Windows.
A vulnerability (CVE-2022-2097) has been identified in the OpenSSL library bundled with Node.js. On 32-bit x86 platforms, OpenSSL's AES-NI assembly implementation of AES in OCB mode can skip one 16-byte block when encrypting or decrypting. The skipped block is never written, so the output can expose 16 bytes of whatever was already in that memory, or, when data is encrypted in place, 16 bytes of the original plaintext.
This flaw maps to CWE-327 (Use of a Broken or Risky Cryptographic Algorithm), where a cryptographic mechanism does not deliver the protection it promises; the root cause is an off-by-one, or fencepost, error (CWE-193). In OpenSSL, a single wrong comparison in the assembly loop drops the last block of the final 96-byte chunk. Data the application believes is encrypted can therefore leave the process partly in the clear.
Exposure is narrow. Only 32-bit x86 builds running on CPUs with AES-NI use the faulty code path, which among official Node.js downloads means the Windows x86 builds, and only applications that explicitly choose an AES-OCB cipher (aes-128-ocb, aes-192-ocb or aes-256-ocb) through the crypto module are affected. TLS and DTLS do not use OCB cipher suites in OpenSSL and are not affected. This issue affects every Node.js release line whose bundled OpenSSL is 1.1.1 through 1.1.1p or 3.0.0 through 3.0.4, up to the versions listed above.
Details
Module Info
- Product: Node.js
- Affected packages: node (bundles OpenSSL under
deps/openssl) - Affected versions: >=10.16.0 <=10.24.1; >=11.9.0 <=11.15.0; >=12.0.0 <=12.22.12; >=13.0.0 <=13.14.0; >=14.0.0 <14.20.0; >=15.0.0 <=15.14.0; >=16.0.0 <16.16.0; >=17.0.0 <=17.9.1; >=18.0.0 <18.5.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 14.20.0, 16.16.0 and 18.5.0 (all July 7, 2022), security releases that upgraded the bundled OpenSSL to 1.1.1q or 3.0.5; Node.js NES v16.20.3 (16.x line, shipped July 30, 2024), a later cumulative build carrying the same fix. The other release lines listed above never received an updated OpenSSL
Vulnerability Info
This Medium-severity vulnerability is found in the OpenSSL library that Node.js bundles and statically links at deps/openssl, in Node.js releases whose bundled OpenSSL predates 1.1.1q or 3.0.5. NVD assigns a CVSS v3.1 score of 5.3, and both OpenSSL and the Node.js security release rate the issue Moderate/Medium.
The 32-bit x86 AES-NI routines for OCB process data six 16-byte blocks (96 bytes) at a time in a fast loop, then hand any remaining zero to five blocks to a separate tail routine. In the vulnerable versions, the check at the end of the fast loop used "jump if below" where it needed "jump if below or equal", so when exactly one full 96-byte chunk remained, the code fell through to the tail routine as if fewer than six blocks were left. The last 16-byte block of that chunk was never processed. The fix corrects the comparison. See the OpenSSL 1.1.1 fix commit for the exact change.
There is no attacker action needed to cause the defect; it happens whenever an affected build encrypts data of a length that hits the boundary. Whoever later receives or stores the output can read the exposed 16 bytes: the in-place case reveals plaintext directly, and the other case can leak unrelated data that was sitting in the output buffer.
Note: 64-bit builds, which are the default nodejs.org downloads on every platform, and applications that do not use AES-OCB are not exposed by this issue.
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.
- Where an upgrade is not yet possible, run a 64-bit Node.js build, or use AES-GCM or ChaCha20-Poly1305 instead of AES-OCB.
- Leverage a commercial support partner like HeroDevs for post-EOL security support, through Node.js NES.
Credits
- Alex Chernyakhovsky from Google (reporter, remediation developer)
- David Benjamin from Google (remediation developer)
- Alejandro Sedeño from Google (remediation developer)