CVE-2022-3602
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 is widely used to build scalable server-side and networking applications.
A buffer overflow vulnerability (CVE-2022-3602) has been identified in the OpenSSL library that Node.js bundles and compiles into the runtime. It allows an attacker to overwrite four attacker-controlled bytes on the stack during X.509 certificate verification, specifically while name constraints are checked against an internationalized email address. Successful exploitation can crash the Node.js process, causing a denial of service, and on some platforms could potentially lead to remote code execution.
Per MITRE (CWE-787, Out-of-bounds Write): “The product writes data past the end, or before the beginning, of the intended buffer.” Here the write lands on the stack, one element past a fixed-size decode buffer, and the value written comes from the certificate presented by the attacker.
This issue affects all Node.js 18.x releases before v18.12.1 and all Node.js 19.x releases before v19.0.1. Node.js release lines that bundle OpenSSL 1.1.1, including 14.x and 16.x, are not affected.
Details
Module Info
- Product: Node.js
- Affected packages: nodejs/node (the Node.js runtime itself, through its bundled OpenSSL 3.0.x library)
- Package manager: Not applicable — Node.js ships as a runtime distribution rather than a registry package.
- Affected versions:
- >=18.0.0 <18.12.1
- >=19.0.0 <19.0.1
- Bundled component affected: OpenSSL 3.0.0 through 3.0.6
- GitHub repository: https://github.com/nodejs/node
- Published packages: https://nodejs.org/en/about/previous-releases
- Upstream advisory: Node.js November 2022 Security Releases and the OpenSSL Security Advisory of 1 November 2022
- GitHub Security Advisory: GHSA-8rwr-x37p-mx23 (filed against the OpenSSL source distribution, not against a Node.js package; no Node.js-ecosystem GHSA exists for this CVE)
- Upstream fixed in: Node.js v18.12.1 and v19.0.1, which raise the bundled OpenSSL to 3.0.7
- Fixed in: Node.js NES v16.20.3 (shipped July 30, 2024, as part of NES's cumulative OpenSSL 3.0.x catch-up release)
Vulnerability Info
This High-severity vulnerability is not in Node.js JavaScript code. It lives in crypto/punycode.c in the OpenSSL 3.0.x library that Node.js compiles into the runtime, so every Node.js build in the affected ranges carries it regardless of what the application does. OpenSSL 3.0.0 through 3.0.6 are vulnerable and OpenSSL 3.0.7 is not; Node.js 18.x and 19.x are the release lines that shipped OpenSSL 3.0.x.
X.509 name constraints let a certificate authority restrict the identities it is permitted to issue certificates for, including email identities. When Node.js verifies a certificate chain through the tls and https modules, OpenSSL performs that check. If a certificate presents an email identity as an internationalized SmtpUTF8Mailbox otherName, OpenSSL first converts the punycode form of the domain back to Unicode with ossl_punycode_decode() so the result can be compared against the constraint. See the name constraints definition in RFC 5280 for how the check is meant to behave.
The decoder guarded its output buffer with an off-by-one bounds test. It compared the number of decoded elements written against the buffer capacity with > where it needed >=, so the loop could write one element past the end of the fixed-size output array. The array holds unsigned int values, which makes that single element a four-byte overwrite of adjacent stack memory with a value derived from the attacker-supplied certificate. The upstream fix changes one operator:
- if (written_out > max_out)
+ if (written_out >= max_out)
return 0;Reaching the decoder requires more than sending a certificate. The name constraint check runs after chain signature verification, so an attacker needs either a certificate authority to have signed the malicious certificate, or the application to keep verifying after it fails to build a path to a trusted issuer. In a Node.js TLS or HTTPS client, that means connecting to a malicious server. In a Node.js TLS server, it means the server requests client authentication and a malicious client connects. Any Node.js code path that asks OpenSSL to verify a chain against name constraints is in scope.
Public denial of service reproducers for this issue exist, including one published by Datadog Security Labs. No working code-execution exploit was known at the time of the advisory.
Note: OpenSSL 1.1.1 and 1.0.2 do not contain the punycode decoder and are not affected, which is why the Node.js 14.x and 16.x lines fall outside this issue. Node.js 17.x also bundled OpenSSL 3.x but had already reached End-of-Life on June 1, 2022, before this fix shipped, and was never updated to receive it. Stack overflow protections present on many platforms and compilers reduce, but do not eliminate, the chance that the four-byte overwrite becomes code execution rather than a crash, and OpenSSL downgraded the issue from Critical to High on that basis before the advisory was published.
Note: A second, closely related issue in the same code, CVE-2022-3786, was fixed in the same Node.js releases. It overflows an arbitrary number of bytes containing the "." character rather than four attacker-controlled bytes, and is documented as a separate entry.
Mitigation
The Node.js 18.x and 19.x release lines are End-of-Life and will not receive any further upstream updates. 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, or, if remaining on an End-of-Life line, to at least v18.12.1 or v19.0.1, which bundle the fixed OpenSSL 3.0.7.
- 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
- Polar Bear (reporter, reported to OpenSSL on October 17, 2022)
- Dr Paul Dale from the OpenSSL Project (remediation developer)