CVE-2025-22150
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() and FormData are not written in Node.js core itself: they are 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 vulnerability caused by insufficiently random values (CVE-2025-22150) has been identified in the undici library bundled with Node.js. When fetch() sends a FormData body, undici encodes it as multipart/form-data and separates the parts with a boundary string that must not be guessable by anyone who can influence the content. However, undici generated that boundary with Math.random(), whose output can be predicted once an observer has seen a few of its values. An attacker who learns enough boundaries could predict the next ones and tamper with multipart requests the application sends to its backend APIs.
This behaviour maps to CWE-330 (Use of Insufficiently Random Values), where a product uses values that are not random enough in a security context that depends on unpredictable numbers. In undici, the boundary is drawn from a non-cryptographic generator, so seeing earlier boundaries lets an attacker work out later ones. With a known boundary, attacker-supplied field content can close a part early and inject new parts into the request.
Exploitation requires an application that sends multipart requests with fetch() both to an attacker-controlled server, which leaks the boundaries, and to a backend API that the attacker wants to tamper with. The attacker also needs influence over some of the data placed in those later requests. The advisory says the attack works only if certain conditions are met, and its workaround is not to send multipart requests to attacker-controlled servers. In Node.js 16.x (from 16.15.0) and 17.x (from 17.5.0), fetch() is only available behind the --experimental-fetch flag; from 18.0.0 it is enabled by default. This issue affects those lines, 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 undici under deps/undici); the standalone undici npm package from 4.5.0 before 5.28.5, from 6.0.0 before 6.21.1, and from 7.0.0 before 7.2.3, is affected in its own right
- Affected versions: >=16.15.0 <=16.20.2 >=17.5.0 <=17.9.1 >=18.0.0 <18.20.6 >=19.0.0 <=19.9.0 >=20.0.0 <20.18.2 >=21.0.0 <=21.7.3 >=22.0.0 <22.13.1 >=23.0.0 <23.6.1
- 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.6 (undici 5.28.5), and 20.18.2, 22.13.1 and 23.6.1 (undici 6.21.1), upstream security releases of January 21, 2025; Node.js NES v18.20.7 (NES 18.x line, shipped January 30, 2025) and v16.20.13 (16.x line, shipped June 25, 2026), the latter for a line that never received an upstream fix before reaching End-of-Life
Vulnerability Info
This Medium-severity vulnerability is found in the multipart/form-data encoder used by fetch() in the undici library that Node.js bundles at deps/undici, in every Node.js release that bundles undici before 5.28.5 or 6.21.1. The GitHub advisory assigns a CVSS v3.1 score of 6.8; the Node.js project also rates it Medium.
When fetch() extracts a FormData body, undici builds a boundary of the form ----formdata-undici-0 followed by eleven digits, and is supposed to make those digits unpredictable. In the vulnerable implementation, the digits came from Math.floor(Math.random() * 1e11). Math.random() is a fast, non-cryptographic generator whose internal state can be recovered from a handful of outputs. The fix generates the digits with crypto.randomInt() whenever the crypto module is available. See the undici fix commit for the exact change.
An attacker would need to receive several multipart requests from the application to recover the generator's state. They would then need to plant content in a later multipart request to a different server, so that the predicted boundary lets them add or alter form parts.
Note: Because the attacker must both observe the application's multipart requests and influence later ones, applications that never send FormData bodies with fetch(), or never send them to untrusted servers, are not exposed by this issue.
Mitigation
Node.js 22.x is still supported and is fixed in 22.13.1 and later. Node.js 23.x reached End-of-Life on June 1, 2025, so the fix in 23.6.1 is the last for that line. All other affected Node.js release lines are 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 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.13.1 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
- parrot409 (reporter)
- Matteo Collina (coordinator)