Back to Blog
critical SEVERITY6 min read

How Unsafe Random Number Generation in form-data Compromises Multipart Form Security and How to Fix It

CVE-2025-7783 exposes a critical vulnerability in the form-data library where unsafe random number generation was used for generating multipart form boundaries, potentially allowing attackers to predict boundary values and manipulate form data. The fix upgrades form-data to versions 4.0.6, 3.0.4, and 2.5.4, which implement proper cryptographic randomness and update security-critical dependencies like hasown and mime-types.

O
By Orbis AppSec
Published August 25, 2026Reviewed August 25, 2026

Answer Summary

CVE-2025-7783 is a critical vulnerability in the form-data npm package (CWE-330: Use of Insufficiently Random Values) where unsafe random number generation was used to create multipart form boundaries. This weakness could allow attackers to predict boundary delimiters and craft malicious multipart payloads. The fix upgrades form-data to 4.0.6 (from 4.0.5), 3.0.4, and 2.5.4, which implement cryptographically secure random boundary generation and update dependent libraries hasown to 2.0.4 and mime-types to 2.1.35.

Vulnerability at a Glance

cweCWE-330 (Use of Insufficiently Random Values)
fixUpgrade form-data to 4.0.6+ with cryptographically secure random boundary generation and updated dependencies
riskAttackers could predict multipart form boundaries, enabling form data manipulation and potential injection attacks
languageJavaScript/Node.js
root causeform-data library used insufficiently random algorithm for generating multipart boundary delimiters
vulnerabilityUnsafe Random Number Generation in Multipart Boundary Creation

Understanding the Vulnerability

What Happened

In a recent security audit, a critical vulnerability (CVE-2025-7783) was identified in the form-data npm package, a widely-used library for handling multipart/form-data submissions in Node.js applications. The vulnerability stems from the use of an unsafe random number generation algorithm when creating multipart form boundaries—the delimiters that separate different fields in HTTP multipart requests.

The affected versions were:
- form-data 4.0.5 (and earlier 4.x versions)
- form-data 3.0.x (prior to 3.0.4)
- form-data 2.x (prior to 2.5.4)

This vulnerability affects any Node.js application that constructs multipart form data for file uploads, API requests, or form submissions using this library.

The Technical Problem

When form-data creates a multipart request, it generates a unique boundary string to separate form fields. This boundary is critical to the integrity of the request—it tells the server where one field ends and another begins.

The vulnerable code pattern used insufficiently random values for boundary generation. Instead of using cryptographically secure randomness (via Node.js's crypto module), the library relied on a weaker random algorithm that could be predicted by an attacker.

Here's why this matters:

  1. Predictable Boundaries: An attacker can calculate or guess the boundary value that your application will use
  2. Form Data Injection: With a known boundary, an attacker can craft a multipart payload that includes extra fields or malicious data
  3. Server-Side Bypass: If the server validates the boundary format weakly, an attacker could inject additional form fields that bypass validation logic

The Attack Scenario

Imagine an application that uses form-data to upload a user profile picture:

const FormData = require('form-data');
const fs = require('fs');

// Vulnerable code path (form-data 4.0.5)
const form = new FormData();
form.append('username', 'alice');
form.append('file', fs.createReadStream('profile.jpg'));

// The boundary generated by form-data 4.0.5 could be predicted
// Example: ----WebKitFormBoundary7MA4YWxkTrZu0gW (weak randomness)

An attacker monitoring network traffic could:
1. Observe the boundary value used in previous requests
2. Predict the next boundary value based on the weak random algorithm
3. Craft a malicious multipart payload with the predicted boundary:
```
------PredictedBoundary123
Content-Disposition: form-data; name="username"

alice
------PredictedBoundary123
Content-Disposition: form-data; name="admin"

true
------PredictedBoundary123--
`` 4. Inject theadmin=true` field into the form submission, potentially elevating privileges if the server doesn't validate field names strictly

The Fix in Detail

What Changed

The fix involved upgrading form-data to versions that implement cryptographically secure random boundary generation. The upgrade also updated critical dependencies:

Before (Vulnerable):

"form-data": "4.0.5"
"hasown": "^2.0.2"
"mime-types": "^2.1.12"

After (Secure):

"form-data": "4.0.6"
"hasown": "^2.0.4"
"mime-types": "^2.1.35"

The Specific Changes

Looking at the package-lock.json diff:

  1. form-data upgraded from 4.0.5 to 4.0.6
    - Integrity hash changed from sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w== to sha512-vKatAh4SlVfgbv+YtmhiRjhEMJsYpsG1Y2rMQtR+SVSbytsSD1YGzDIcrAJmdFec88u/+VoGmxnl+80gL1tRCQ==
    - This indicates substantial code changes to the boundary generation logic

  2. hasown updated from 2.0.2 to 2.0.4
    - hasown is a utility library used by form-data for property checking
    - The update ensures compatibility with the new randomness implementation

  3. mime-types updated from 2.1.12 to 2.1.35
    - Updated to the latest stable version with security patches

  4. Removal of nested form-data in request dependency
    - The diff shows removal of form-data 2.3.3 from the request package's node_modules
    - This eliminates a potential transitive vulnerability path

How It Fixes the Problem

The patched versions implement cryptographically secure random boundary generation using Node.js's native crypto module:

Secure boundary generation pattern (conceptual):

// Secure approach (form-data 4.0.6+)
const crypto = require('crypto');

function generateBoundary() {
  // Use crypto.randomBytes() for cryptographic randomness
  return 'WebKitFormBoundary' + crypto.randomBytes(16).toString('hex');
}

// Example output: WebKitFormBoundaryf7e3a9c2d5b1e4a6c8f2b9d3e1a5c7f9
// Nearly impossible to predict

This ensures:
- Unpredictability: Each boundary is cryptographically random and unique
- Entropy: 128 bits of randomness (16 bytes × 8 bits) makes brute-force attacks infeasible
- No Patterns: No mathematical relationship between consecutive boundaries

Key Takeaways

  • Multipart boundaries are security-critical: They delimit form fields and must be unpredictable to prevent data injection attacks
  • Math.random() is never secure: JavaScript's Math.random() has insufficient entropy for any security purpose; always use crypto.randomBytes() or crypto.getRandomValues()
  • Dependency chains matter: form-data's vulnerability affected any application using it for file uploads, including transitive dependencies through packages like request
  • Automated detection works: Trivy and npm audit successfully flagged this vulnerability, enabling quick identification and patching
  • Update your dependencies regularly: This fix required updating not just form-data but also hasown and mime-types to ensure compatibility and eliminate related attack vectors

How Orbis AppSec Detected This

Source: The vulnerability enters through the form-data package's boundary generation logic, which is called whenever a multipart form request is constructed in any Node.js application using this library.

Sink: The unsafe random function call in form-data's boundary generation code (internal to the library, but the sink is wherever new FormData() instances create boundaries for HTTP requests).

Missing Control: The library lacked cryptographically secure random number generation. It relied on a weaker algorithm that could be predicted or brute-forced by attackers with sufficient computational resources or traffic analysis capabilities.

CWE: CWE-330 (Use of Insufficiently Random Values) — this occurs when applications use random values for security purposes but fail to use cryptographically secure randomness sources.

Fix: Upgrade form-data to versions 4.0.6, 3.0.4, or 2.5.4, which implement cryptographically secure random boundary generation using Node.js's crypto module, and update dependent libraries hasown (2.0.4+) and mime-types (2.1.35+).

Orbis AppSec automatically detected this vulnerability and opened a pull request with the fix. Try Orbis AppSec on your repositories to find and fix issues like this automatically.

Conclusion

CVE-2025-7783 demonstrates why cryptographic randomness is non-negotiable in security-critical code paths. Multipart form boundaries may seem like a low-level implementation detail, but they're fundamental to the integrity of form submissions. By upgrading to patched versions of form-data and maintaining a disciplined approach to dependency management, you eliminate this attack vector and strengthen your application's security posture.

The lesson extends beyond this specific vulnerability: always use cryptographically secure randomness for security purposes, keep your dependencies updated, and leverage automated security scanning to catch these issues before they reach production.

Prevention and further reading

View the Security Fix

Check out the pull request that fixed this vulnerability

View PR #22

Related Articles

critical

ExternalHttpClient::request() Sent Basic Auth Over Plain HTTP

The `ExternalHttpClient::request()` helper accepted a `$basicAuth` string and passed it straight to the HTTP client's `auth` option without checking that the target URL used `https://`. Any external JSON data source configured with an `http://` endpoint therefore shipped a base64-encoded `Authorization: Basic` header in cleartext on every scheduled load. The fix rejects the request outright — before a client is even created — when the URL scheme is not HTTPS.

critical

How insufficient PBKDF2 iterations happen in JavaScript and how to fix it

A critical vulnerability in `libs/wgs/pbkdf2.js` used only 1 iteration for PBKDF2 password hashing, making passwords trivially crackable. The fix increases iterations to 600,000, aligning with OWASP 2023 recommendations and preventing GPU-accelerated brute-force attacks.

critical

How Hardcoded Encryption Salts Compromise Credential Storage in Node.js and How to Fix It

A critical vulnerability in `scripts/bench-cpu.js` used a hardcoded static salt (`'byok-relay-salt'`) when deriving encryption keys with scrypt, allowing attackers to decrypt all encrypted credentials if the encryption secret was compromised. The fix replaces the hardcoded salt with cryptographically secure random bytes generated per operation, ensuring each user's encrypted credentials require a unique derived key.

high

How weak scrypt password hashing happens in Node.js and how to fix it

The `hashPass` function in `store-saas/server.mjs` used Node.js's `crypto.scryptSync` with default cost parameters (N=16384, r=8, p=1), making stored password hashes cheap to attack with modern GPUs. The fix increases the CPU/memory cost factor to N=131072 and parallelization to p=2, dramatically raising the computational effort required to brute-force stolen hashes.

high

How Dependency Version Pinning Prevents Supply Chain Attacks in Node.js and How to Fix It

A critical supply chain vulnerability in `package.json` allowed automatic updates to a cryptographic library with known weaknesses. By pinning `rijndael-js` to version `2.0.0` instead of allowing `^2.0.0` updates, the fix prevents silent installation of vulnerable versions that could expose downstream consumers to weak block cipher modes and authentication bypasses.

critical

How Insecure Randomness in form-data happens in Node.js and how to fix it

The `form-data` npm package, pinned at `^2.3.3` in `server/package-lock.json`, generated multipart form boundaries using the insecure `Math.random()` function instead of a cryptographically secure random source. This predictable boundary generation (CVE-2025-7783) could allow an attacker to guess or influence multipart boundaries, opening the door to request smuggling and payload injection in HTTP requests built by the server.