CVE-2025-22150
Medium · 6.8CVSS
6.8
EPSS
0.8%
Published
Jan 21, 2025
CISA due date
—
Cloudanix analysis
Some Node.js applications may create upload requests in a predictable way, which could let an attacker tamper with certain follow-on requests if the application sends uploads to untrusted destinations.
- Exploitation
- Requires User Interaction
- Attacker needs
- User Interaction
- Complexity
- High
- Impact
- Data Tampering
- Component
- Library
- Class
- Cryptographic Weakness
- Remediation
- Upgrade
- Effort
- Medium
- Patch risk
- Low
What it actually does
Undici generated multipart/form-data boundaries using Math.random() in affected versions starting with 4.5.0 and before 5.28.5, 6.21.1, and 7.2.3. Because Math.random() is not a cryptographically secure random number generator, an attacker who can observe enough generated boundary values may be able to predict future multipart boundaries. If an application can be induced to send multipart requests to an attacker-controlled endpoint and later sends multipart requests to sensitive backend APIs, the attacker may be able to craft input that collides with or manipulates multipart parsing, potentially altering request content and compromising confidentiality and integrity. The attack requires specific application behavior and user or application interaction, which raises exploitation complexity.
Why it matters to the business
Successful exploitation could allow manipulation of application-to-backend API requests, potentially causing unauthorized data submission, altered file uploads, or exposure of sensitive data handled in multipart requests. The risk is most relevant for Node.js applications that both use Undici for multipart/form-data and can be made to send multipart requests to attacker-controlled destinations. The issue is not listed in CISA KEV, is not known to be used in ransomware campaigns, and has a low EPSS score, but affected dependency versions may be widely embedded through transitive Node.js dependencies, so software composition review is important.
How an attack unfolds
An attacker first needs a path to make the target application issue multipart/form-data requests to an attacker-controlled server, such as through a webhook, integration, URL submission workflow, or user-driven upload forwarding feature. By observing several multipart boundaries generated by the vulnerable Undici client, the attacker may infer enough Math.random() output to predict future boundary values. The attacker then uses that prediction to prepare multipart content intended to interfere with how a later request is parsed by a backend API. If the application subsequently sends attacker-influenced multipart data to a sensitive backend while using a predictable boundary, the attacker may cause extra fields, altered parts, or malformed parsing outcomes that affect the backend request. This is a conditional attack: without a mechanism to observe generated multipart requests and influence later backend-bound multipart content, exploitation is unlikely.
How to fix it
Upgrade Undici to a fixed version: 5.28.5 or later for the 5.x line, 6.21.1 or later for the 6.x line, or 7.2.3 or later for the 7.x line. For source builds, ensure the fix corresponding to commit 6139ed2e0c787853243de58ef7c4301b26ca66f2 is present. Review both direct and transitive dependencies because Undici may be pulled in by frameworks, SDKs, or Node.js HTTP client wrappers. If immediate upgrade is not possible, prevent the application from issuing multipart requests to attacker-controlled or user-supplied destinations, restrict outbound HTTP destinations with allowlists, and avoid forwarding attacker-controlled multipart content to sensitive backend APIs without normalization and validation.
How to confirm the fix worked
Confirm the deployed dependency tree no longer contains affected Undici versions. Use package manager tooling such as npm ls undici, pnpm why undici, yarn why undici, or software composition analysis output to verify all resolved versions are 5.28.5, 6.21.1, 7.2.3, or newer as appropriate. Inspect lockfiles and container images, not only package.json declarations, because transitive dependencies may pin older versions. Where source builds are used, verify the patch commit 6139ed2e0c787853243de58ef7c4301b26ca66f2 or equivalent change is included. Functionally test application features that send multipart/form-data to ensure uploads and integrations still work after upgrade. To assess exposure, identify code paths that send multipart requests to user-controlled URLs and determine whether any sensitive backend multipart calls can include attacker-influenced content.
Typical attack path
- Identify a Node.js application or service using an affected Undici version for multipart/form-data requests.
- Find a feature that causes the application to send multipart requests to an attacker-controlled URL or service.
- Collect multiple multipart boundary values generated by the vulnerable client.
- Use predictability in Math.random()-derived values to estimate future multipart boundaries.
- Craft multipart content that is designed to collide with or manipulate parsing of a later backend-bound request.
- Trigger the application to send the crafted multipart request to a sensitive backend API.
- Leverage altered backend request contents to access data, change submitted fields, or affect file/upload handling.
How to detect it
There is no universal exploit signature for this issue, and exploitation is highly application-dependent. To look for prior exploitation, correlate outbound HTTP client logs, proxy logs, egress firewall logs, webhook delivery logs, and application request logs. Focus on periods when affected Undici versions were deployed. Look for multipart/form-data requests from the application to unusual or user-supplied external domains, especially repeated requests that could have allowed boundary observation. Then correlate those events with subsequent multipart requests to backend APIs that contain unexpected extra fields, duplicated part names, malformed multipart separators, parse errors, unusual file metadata, or authorization-sensitive field changes. Useful log sources include Node.js application logs, reverse proxy access logs, outbound proxy logs, API gateway logs, WAF logs, backend upload service logs, and dependency/runtime inventory. Because the weakness concerns predictable boundary generation rather than a fixed payload, treat detections as behavioral: untrusted outbound multipart traffic plus anomalous backend multipart parsing is more meaningful than any single string.
- Content-Type: multipart/form-data; boundary=----formdata-undici-
- ----formdata-undici-
- node_modules/undici/package.json
- "undici"
What your security team should do
- Inventory Node.js services, containers, serverless functions, and build artifacts for Undici versions from 4.5.0 up to but not including 5.28.5, 6.21.1, or 7.2.3.
- Prioritize remediation for applications that send multipart/form-data to user-supplied URLs, external webhooks, third-party integrations, or untrusted domains.
- Upgrade Undici to a fixed version and refresh lockfiles and container images so transitive dependency copies are actually replaced.
- Implement outbound destination allowlisting for server-side HTTP requests, especially for features that support uploads, webhooks, URL fetchers, or integrations.
- Add application-level safeguards that normalize or regenerate multipart bodies before forwarding them to backend APIs.
- Review logs for historical outbound multipart requests to untrusted domains followed by unusual backend multipart API behavior.
- Keep this issue below actively exploited KEV-level emergencies unless local exposure analysis shows attacker-observable multipart generation and sensitive backend forwarding paths.
The record
Undici is an HTTP/1.1 client. Starting in version 4.5.0 and prior to versions 5.28.5, 6.21.1, and 7.2.3, undici uses `Math.random()` to choose the boundary for a multipart/form-data request. It is known that the output of `Math.random()` can be predicted if several of its generated values are known. If there is a mechanism in an app that sends multipart requests to an attacker-controlled website, they can use this to leak the necessary values. Therefore, an attacker can tamper with the requests going to the backend APIs if certain conditions are met. This is fixed in versions 5.28.5, 6.21.1, and 7.2.3. As a workaround, do not issue multipart requests to attacker controlled servers.
Affected packages
| Ecosystem | Package | Introduced | Fixed |
|---|---|---|---|
| npm | undici | 4.5.0 | 5.28.5 |
| npm | undici | 6.0.0 | 6.21.1 |
| npm | undici | 7.0.0 | 7.2.3 |
| AlmaLinux:8 | nodejs | 0 | 1:20.18.2-1.module_el8.10.0+3958+472a6467 |
| AlmaLinux:8 | nodejs | 0 | 1:18.20.6-1.module_el8.10.0+3960+fcfbf683 |
| AlmaLinux:8 | nodejs | 0 | 1:22.13.1-1.module_el8.10.0+3961+6a788e57 |
| AlmaLinux:8 | nodejs-devel | 0 | 1:20.18.2-1.module_el8.10.0+3958+472a6467 |
| AlmaLinux:8 | nodejs-devel | 0 | 1:18.20.6-1.module_el8.10.0+3960+fcfbf683 |
| AlmaLinux:8 | nodejs-devel | 0 | 1:22.13.1-1.module_el8.10.0+3961+6a788e57 |
| AlmaLinux:8 | nodejs-docs | 0 | 1:20.18.2-1.module_el8.10.0+3958+472a6467 |
| AlmaLinux:8 | nodejs-docs | 0 | 1:18.20.6-1.module_el8.10.0+3960+fcfbf683 |
| AlmaLinux:8 | nodejs-docs | 0 | 1:22.13.1-1.module_el8.10.0+3961+6a788e57 |
| AlmaLinux:8 | nodejs-full-i18n | 0 | 1:20.18.2-1.module_el8.10.0+3958+472a6467 |
| AlmaLinux:8 | nodejs-full-i18n | 0 | 1:18.20.6-1.module_el8.10.0+3960+fcfbf683 |
| AlmaLinux:8 | nodejs-full-i18n | 0 | 1:22.13.1-1.module_el8.10.0+3961+6a788e57 |
| AlmaLinux:8 | nodejs-libs | 0 | 1:22.13.1-1.module_el8.10.0+3961+6a788e57 |
| AlmaLinux:8 | nodejs-nodemon | 0 | 3.0.1-1.module_el8.8.0+3613+1ed8c91d |
| AlmaLinux:8 | nodejs-packaging | 0 | 2021.06-4.module_el8.7.0+3343+ea2b7901 |
| AlmaLinux:8 | nodejs-packaging | 0 | 2021.06-4.module_el8.10.0+3961+6a788e57 |
| AlmaLinux:8 | nodejs-packaging-bundler | 0 | 2021.06-4.module_el8.10.0+3958+472a6467 |
| AlmaLinux:8 | nodejs-packaging-bundler | 0 | 2021.06-4.module_el8.10.0+3961+6a788e57 |
| AlmaLinux:8 | npm | 0 | 1:10.8.2-1.20.18.2.1.module_el8.10.0+3958+472a6467 |
| AlmaLinux:8 | npm | 0 | 1:10.8.2-1.18.20.6.1.module_el8.10.0+3960+fcfbf683 |
| AlmaLinux:8 | npm | 0 | 1:10.9.2-1.22.13.1.1.module_el8.10.0+3961+6a788e57 |
| AlmaLinux:8 | v8-12.4-devel | 0 | 3:12.4.254.21-1.22.13.1.1.module_el8.10.0+3961+6a788e57 |
| AlmaLinux:9 | nodejs | 0 | 1:20.18.2-1.module_el9.5.0+137+381f3eaf |
| AlmaLinux:9 | nodejs | 0 | 1:18.20.6-1.module_el9.5.0+136+92f38f3c |
| AlmaLinux:9 | nodejs | 0 | 1:22.13.1-1.module_el9.5.0+139+09296491 |
| AlmaLinux:9 | nodejs-devel | 0 | 1:20.18.2-1.module_el9.5.0+137+381f3eaf |
| AlmaLinux:9 | nodejs-devel | 0 | 1:18.20.6-1.module_el9.5.0+136+92f38f3c |
| AlmaLinux:9 | nodejs-devel | 0 | 1:22.13.1-1.module_el9.5.0+139+09296491 |
| AlmaLinux:9 | nodejs-docs | 0 | 1:20.18.2-1.module_el9.5.0+137+381f3eaf |
| AlmaLinux:9 | nodejs-docs | 0 | 1:18.20.6-1.module_el9.5.0+136+92f38f3c |
| AlmaLinux:9 | nodejs-docs | 0 | 1:22.13.1-1.module_el9.5.0+139+09296491 |
| AlmaLinux:9 | nodejs-full-i18n | 0 | 1:20.18.2-1.module_el9.5.0+137+381f3eaf |
| AlmaLinux:9 | nodejs-full-i18n | 0 | 1:18.20.6-1.module_el9.5.0+136+92f38f3c |
| AlmaLinux:9 | nodejs-full-i18n | 0 | 1:22.13.1-1.module_el9.5.0+139+09296491 |
| AlmaLinux:9 | nodejs-libs | 0 | 1:22.13.1-1.module_el9.5.0+139+09296491 |
| AlmaLinux:9 | nodejs-nodemon | 0 | 3.0.1-1.module_el9.2.0+36+853e48f5 |
| AlmaLinux:9 | nodejs-nodemon | 0 | 3.0.1-1.module_el9.5.0+136+92f38f3c |
| AlmaLinux:9 | nodejs-packaging | 0 | 2021.06-4.module_el9.3.0+88+29afeaa2 |
| AlmaLinux:9 | nodejs-packaging | 0 | 2021.06-4.module_el9.5.0+136+92f38f3c |
| AlmaLinux:9 | nodejs-packaging-bundler | 0 | 2021.06-4.module_el9.5.0+124+df88fe49 |
| AlmaLinux:9 | nodejs-packaging-bundler | 0 | 2021.06-4.module_el9.5.0+139+09296491 |
| AlmaLinux:9 | npm | 0 | 1:10.8.2-1.20.18.2.1.module_el9.5.0+137+381f3eaf |
| AlmaLinux:9 | npm | 0 | 1:10.8.2-1.18.20.6.1.module_el9.5.0+136+92f38f3c |
| AlmaLinux:9 | npm | 0 | 1:10.9.2-1.22.13.1.1.module_el9.5.0+139+09296491 |
| AlmaLinux:9 | v8-12.4-devel | 0 | 3:12.4.254.21-1.22.13.1.1.module_el9.5.0+139+09296491 |
| Alpine:v3.21 | nodejs | 0 | 22.13.1-r0 |
| Alpine:v3.22 | nodejs | 0 | 22.13.1-r0 |
| Chainguard | jitsucom-jitsu | 0 | 2.8.6-r1 |
| Chainguard | jitsucom-jitsu-console | 0 | 2.8.6-r1 |
| Chainguard | jitsucom-jitsu-rotor | 0 | 2.8.6-r1 |
| Chainguard | kibana-8 | 0 | 8.17.1-r1 |
| Chainguard | kibana-8-bitnami | 0 | 8.17.1-r1 |
| Chainguard | kibana-8-iamguarded | 0 | 8.17.1-r1 |
| Debian:12 | node-undici | 0 | No fix |
| Debian:13 | node-undici | 0 | No fix |
| Debian:13 | node-undici | 0 | 7.3.0+dfsg1+~cs24.12.11-1 |
| Rocky Linux:8 | nodejs | 0 | 1:20.18.2-1.module+el8.10.0+1932+2f13f218 |
| Rocky Linux:8 | nodejs | 0 | 1:18.20.6-1.module+el8.10.0+1934+a521c41f |
| Rocky Linux:8 | nodejs | 0 | 1:22.13.1-1.module+el8.10.0+1935+d3cbe60f |
| Rocky Linux:8 | nodejs-nodemon | 0 | 0:3.0.1-1.module+el8.10.0+1666+930e28e8 |
| Rocky Linux:8 | nodejs-packaging | 0 | 0:2021.06-4.module+el8.10.0+1667+4a788d89 |
| Rocky Linux:9 | nodejs-nodemon | 0 | 0:3.0.1-1.module+el9.4.0+25495+f51dca35 |
| Rocky Linux:9 | nodejs-nodemon | 0 | 0:3.0.1-1.module+el9.6.0+32144+1d29a396 |
| Rocky Linux:9 | nodejs-nodemon | 0 | 0:3.0.1-1.module+el9.6.0+32322+a8b1fd01 |
| Rocky Linux:9 | nodejs-packaging | 0 | 0:2021.06-4.module+el9.4.0+25495+f51dca35 |
| Rocky Linux:9 | nodejs-packaging | 0 | 0:2021.06-4.module+el9.5.0+31770+0da7192d |
| SUSE:Linux Enterprise High Performance Computing 15 SP4-ESPOS | nodejs18 | 0 | 18.20.6-150400.9.33.1 |
| SUSE:Linux Enterprise High Performance Computing 15 SP4-LTSS | nodejs18 | 0 | 18.20.6-150400.9.33.1 |
| SUSE:Linux Enterprise High Performance Computing 15 SP5-ESPOS | nodejs18 | 0 | 18.20.6-150400.9.33.1 |
| SUSE:Linux Enterprise High Performance Computing 15 SP5-ESPOS | nodejs20 | 0 | 20.18.2-150500.11.18.1 |
| SUSE:Linux Enterprise High Performance Computing 15 SP5-LTSS | nodejs18 | 0 | 18.20.6-150400.9.33.1 |
| SUSE:Linux Enterprise High Performance Computing 15 SP5-LTSS | nodejs20 | 0 | 20.18.2-150500.11.18.1 |
| SUSE:Linux Enterprise Module for Web and Scripting 15 SP6 | nodejs20 | 0 | 20.18.2-150600.3.9.1 |
| SUSE:Linux Enterprise Module for Web and Scripting 15 SP6 | nodejs22 | 0 | 22.13.1-150600.13.6.1 |
| SUSE:Linux Enterprise Server 12 SP5-LTSS | nodejs18 | 0 | 18.20.6-8.33.1 |
| SUSE:Linux Enterprise Server 15 SP4-LTSS | nodejs18 | 0 | 18.20.6-150400.9.33.1 |
| SUSE:Linux Enterprise Server 15 SP5-LTSS | nodejs18 | 0 | 18.20.6-150400.9.33.1 |
| SUSE:Linux Enterprise Server 15 SP5-LTSS | nodejs20 | 0 | 20.18.2-150500.11.18.1 |
| SUSE:Linux Enterprise Server LTSS Extended Security 12 SP5 | nodejs18 | 0 | 18.20.6-8.33.1 |
| SUSE:Linux Enterprise Server for SAP Applications 15 SP4 | nodejs18 | 0 | 18.20.6-150400.9.33.1 |
| SUSE:Linux Enterprise Server for SAP Applications 15 SP5 | nodejs18 | 0 | 18.20.6-150400.9.33.1 |
| SUSE:Linux Enterprise Server for SAP Applications 15 SP5 | nodejs20 | 0 | 20.18.2-150500.11.18.1 |
| SUSE:Manager Server 4.3 | nodejs18 | 0 | 18.20.6-150400.9.33.1 |
| Ubuntu:24.04:LTS | node-undici | 0 | No fix |
| Ubuntu:24.10 | node-undici | 0 | No fix |
| Ubuntu:25.04 | node-undici | 0 | No fix |
| Ubuntu:25.10 | node-undici | 0 | No fix |
| Wolfi | jitsucom-jitsu | 0 | 2.8.6-r1 |
| Wolfi | jitsucom-jitsu-console | 0 | 2.8.6-r1 |
| Wolfi | jitsucom-jitsu-rotor | 0 | 2.8.6-r1 |
| openSUSE:Leap 15.6 | nodejs20 | 0 | 20.18.2-150600.3.9.1 |
| openSUSE:Leap 15.6 | nodejs22 | 0 | 22.13.1-150600.13.6.1 |
| openSUSE:Tumbleweed | nodejs22 | 0 | 22.13.0-1.1 |
| openSUSE:Tumbleweed | nodejs24 | 0 | 24.11.1-2.1 |
| openSUSE:Tumbleweed | nodejs26 | 0 | 26.3.1-1.1 |
Related vulnerabilities
- GHSA-g8m3-5g58-fq7m undici vulnerable to Set-Cookie SameSite attribute downgrade via permissive substring… Also affects undici
- GHSA-vxpw-j846-p89q undici WebSocket client vulnerable to denial of service via fragment count bypass Also affects undici
- GHSA-p88m-4jfj-68fv undici vulnerable to HTTP header injection via Set-Cookie percent-decoding Also affects undici
- GHSA-hm92-r4w5-c3mj undici vulnerable to cross-origin request routing via SOCKS5 proxy pool reuse Also affects undici
- GHSA-35p6-xmwp-9g52 undici vulnerable to HTTP response queue poisoning via keep-alive socket reuse Also affects undici
- GHSA-vmh5-mc38-953g undici vulnerable to TLS certificate validation bypass via dropped requestTls in SOCKS5… Also affects undici
- GHSA-pr7r-676h-xcf6 undici vulnerable to cross-user information disclosure via shared cache whitespace bypass Also affects undici
- GHSA-38rv-x7px-6hhq undici WebSocket client vulnerable to denial of service via cumulative fragment bypass Also affects undici