CVE-2024-30261
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. Node.js's global fetch() is not written in Node.js core itself: it is provided by undici, an HTTP/1.1 client maintained by the Node.js project, which Node.js bundles at deps/undici and ships inside the runtime. A vulnerability in the bundled undici therefore affects fetch() in Node.js directly, even for applications that never install the undici package from npm.
A data integrity vulnerability (CVE-2024-30261) has been identified in the undici library bundled with Node.js. fetch() accepts an integrity option, a Subresource Integrity string naming a hash algorithm and the expected hash of the response body, and should reject any response that does not match it. However, undici's parsing of that string was too permissive when an algorithm was given but the hash value was malformed. An attacker who can alter the integrity value can then get a tampered response accepted as valid.
This behaviour maps to CWE-284 (Improper Access Control), the weakness assigned in the CVE record, where a product does not correctly restrict access to a resource from an unauthorized actor. The GitHub advisory files it under CWE-657 (Violation of Secure Design Principles) instead. In undici, the safeguard that fails is the integrity check, which can be satisfied by input it should reject. This undermines the guarantee that fetched content is exactly what the application expected.
Exploitation requires an application that passes an integrity value to fetch() and an attacker who can change that value, as well as serve or tamper with the response. The advisory's only workaround is to make sure the integrity value cannot be tampered with, which also describes the main precondition. In Node.js, the integrity check first appears in the bundled undici in 16.18.0 and 18.9.0. On 16.x, fetch() is only available behind the --experimental-fetch flag; from 18.0.0 it is enabled by default. Node.js 17.x never bundled a version with this check. This issue affects those lines, 19.x, and 18.x, 20.x and 21.x before the versions listed above.
Details
Module Info
- Product: Node.js
- Affected packages: node (bundles undici under deps/undici); the standalone undici npm package before 5.28.4, and from 6.0.0 before 6.11.1, is affected in its own right
- Affected versions: >=16.18.0 <=16.20.2 >=18.9.0 <18.20.1 >=19.0.0 <=19.9.0 >=20.0.0 <20.12.1 >=21.0.0 <21.7.2
- 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 18.20.1, 20.12.1, and 21.7.2 (upstream fixes, released April 3, 2024 with undici 5.28.4, while those lines were still supported); Node.js NES v16.20.5 (16.x line, shipped January 16, 2025), which never received an upstream fix before reaching End-of-Life
Vulnerability Info
This Low-severity vulnerability is found in the Subresource Integrity check of fetch() in the undici library that Node.js bundles at deps/undici, in every Node.js release whose bundled undici has the check but predates 5.28.4. NVD assigns a CVSS v3.1 score of 3.5; the GitHub advisory rates it Low at 2.6.
When a response body arrives, undici's bytesMatch() parses the integrity metadata with parseMetadata(), picks the strongest listed algorithm, hashes the body and compares the result with the expected value. In the vulnerable implementation, the regular expression that extracted the expected hash accepted almost any characters after the algorithm prefix, rather than only a well-formed base64 or base64url digest. Combined with how padding was trimmed before comparing, a malformed hash value could lead to a body that did not match being accepted. The fix replaces the pattern with one that only accepts valid base64 or base64url digests, and reworks how the strongest algorithm is selected and the values compared. See the undici fix commits 2b39440 and d542b8c for the exact changes.
An attacker would need to influence the integrity value an application hands to fetch() and also control or tamper with the fetched content.
Note: Because the integrity value has to be attacker-controlled, applications that hard-code their integrity values, or do not use the integrity option at all, are not exposed by this issue.
Mitigation
The Node.js 16.x, 18.x, 19.x, 20.x and 21.x release lines are all past their support window and will not receive further upstream updates. Node.js 16.x reached End-of-Life on September 11, 2023; 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 a currently supported Node.js LTS release (22.x or 24.x), both of which bundle an undici version that already 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
- Uzlopak (reporter)