Skip to content

Guard deepMerge against prototype pollution#10109

Closed
gunjanjaswal wants to merge 2 commits into
RaspberryPiFoundation:mainfrom
gunjanjaswal:fix/blockly-deepmerge-proto-pollution
Closed

Guard deepMerge against prototype pollution#10109
gunjanjaswal wants to merge 2 commits into
RaspberryPiFoundation:mainfrom
gunjanjaswal:fix/blockly-deepmerge-proto-pollution

Conversation

@gunjanjaswal

Copy link
Copy Markdown

The basics

  • I validated my changes

The details

Resolves

Fixes #10048

Proposed Changes

deepMerge walks source with for...in and never skips the prototype-pollution keys, so a source object with an own enumerable __proto__ (which is exactly what JSON.parse produces) gets written onto Object.prototype during the recursive merge. This adds a small guard that skips __proto__, constructor, and prototype before merging each key.

Reason for Changes

Blockly.utils.object.deepMerge is a public, package-root-reachable API. If a host app passes any user-influenced data through it, deepMerge({}, JSON.parse('{"__proto__":{"x":"y"}}')) sets Object.prototype.x, which then leaks onto every plain object in the process (CWE-1321). The guard is minimal and leaves behavior unchanged for all normal keys.

Test Coverage

Added a case to the existing deepMerge mocha suite in utils_test.js: it merges a JSON.parse('{"__proto__": {"blocklyPolluted": "yes"}}') payload into {} and asserts Object.prototype.blocklyPolluted stays undefined. It fails before the guard and passes after. I don't have the Blockly build toolchain set up locally, so I leaned on the added test plus CI rather than a local full run.

Documentation

None needed, behavior is unchanged for normal keys.

Additional Information

On #10048 a maintainer mentioned you might prefer to drop deepMerge in favor of the spread operator. Happy to do that instead if you'd rather remove the function than harden it; this guard is the minimal fix in the meantime.

@gunjanjaswal gunjanjaswal requested a review from a team as a code owner July 4, 2026 23:04
@gunjanjaswal gunjanjaswal requested a review from maribethb July 4, 2026 23:04
@gunjanjaswal gunjanjaswal deleted the fix/blockly-deepmerge-proto-pollution branch July 4, 2026 23:04
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.

Prototype pollution in Blockly.utils.object.deepMerge

2 participants