Skip to content

fix: prevent prototype confusion via __proto__ key in Object.fromEntries polyfill - #4335

Open
prasanna8585 wants to merge 1 commit into
google:masterfrom
prasanna8585:fix/fromentries-proto-confusion
Open

fix: prevent prototype confusion via __proto__ key in Object.fromEntries polyfill#4335
prasanna8585 wants to merge 1 commit into
google:masterfrom
prasanna8585:fix/fromentries-proto-confusion

Conversation

@prasanna8585

Copy link
Copy Markdown

Object.fromEntries's polyfill assigns each key/value pair with obj[key] = val. When the source iterable yields a pair whose key is the string "__proto__", that plain assignment invokes Object.prototype's __proto__ accessor setter instead of creating an own property — reassigning the returned object's own [[Prototype]] to the caller-supplied value, rather than storing it as an own "__proto__" property as ECMA-262 24.1.1.2's CreateDataPropertyOrThrow requires.

Any code that builds an object from an untrusted iterable of key/value pairs (URLSearchParams, parsed JSON pairs, form data, etc.) via this polyfill is affected: an attacker-supplied ["__proto__", someObject] pair silently reassigns the resulting object's prototype, so inherited properties on someObject appear to be legitimate values on the returned object to any code inspecting it afterward.

This is the same defect class already fixed for Object.getOwnPropertyDescriptors's polyfill in this codebase (f32e2796f, "Fix Object.getOwnPropertyDescriptors polyfill to prevent prototype injection"), which switched to Object.defineProperty for the identical reason. This applies the same fix here.

Verified with a standalone Node script exercising the extracted polyfill logic — before the fix, an attacker-controlled __proto__ key reassigns the object's prototype and inherited properties (e.g. isAdmin) become visible on the result; after the fix, the prototype stays Object.prototype, __proto__ is stored as a normal own property (matching spec), and ordinary key/value, duplicate-key, and symbol-key behavior are all unchanged.

…ies polyfill

Object.fromEntries assigned each key/value pair directly with
obj[key] = val. When the source iterable yields a pair whose key is
the string "__proto__", that assignment invokes Object.prototype's
__proto__ accessor setter instead of creating an own property,
reassigning the returned object's own [[Prototype]] to the
caller-supplied value rather than storing it as an own "__proto__"
property, per ECMA-262 24.1.1.2's CreateDataPropertyOrThrow
requirement.

Any code building an object from an untrusted iterable of key/value
pairs (URLSearchParams, parsed JSON pairs, form data, etc.) via this
polyfill is affected: an attacker-supplied ["__proto__", someObject]
pair silently reassigns the resulting object's prototype, letting
inherited properties on someObject appear to be legitimate values on
the returned object to any code that checks it afterward.

This is the same defect class already fixed for the
Object.getOwnPropertyDescriptors polyfill in this codebase
(commit f32e279), which switched to Object.defineProperty for the
same reason. Apply the identical fix here.

Verified with a standalone Node script exercising the extracted
polyfill logic: the exploit (attacker-controlled __proto__ key
reassigning the prototype) is closed, ordinary key/value behavior is
unchanged, duplicate-key last-wins semantics are preserved, and
symbol keys continue to work.
@concavelenz

Copy link
Copy Markdown
Contributor

We already have a change internal to Google under review that should be pushed out in the next few day.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants