Skip to content

fix(decode): preserve __proto__ map keys as own properties#185

Open
spokodev wants to merge 1 commit into
rvagg:masterfrom
spokodev:fix/decode-proto-map-key
Open

fix(decode): preserve __proto__ map keys as own properties#185
spokodev wants to merge 1 commit into
rvagg:masterfrom
spokodev:fix/decode-proto-map-key

Conversation

@spokodev

@spokodev spokodev commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Decoding a CBOR map with a "__proto__" text key assigned the value with obj[key] = value, which invokes the prototype setter on the plain object rather than creating an own property. The entry was silently dropped and the decoded object's prototype could be mutated, so valid input did not round trip. rejectDuplicateMapKeys also failed to reject repeated "__proto__" keys because the earlier assignment never created an own property for the duplicate check to find.

This assigns the key with a data property descriptor, so it becomes a normal own enumerable property and the prototype is left untouched. Adds tests for the round trip and the duplicate-key rejection.

Decoding a CBOR map with a "__proto__" text key assigned the value with
`obj[key] = value`, which invokes the prototype setter on the plain object
rather than creating an own property. The entry was silently dropped and the
decoded object's prototype was mutated, so valid input did not round-trip.
`rejectDuplicateMapKeys` also failed to reject repeated "__proto__" keys
because the earlier assignment never created an own property for the
duplicate check to find.

Assign the "__proto__" key with a data property descriptor so it becomes a
normal own enumerable property and the prototype is left untouched.
Comment on lines +70 to +71
assert.strictEqual(obj.__proto__, 1) // eslint-disable-line no-proto
assert.strictEqual(Object.getPrototypeOf(obj), Object.prototype, 'prototype is unchanged')

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should run this without your change in decode.js, I'm pretty sure it'll pass anyway because __proto__ can only be set to an object or null, not primitives/scalars like 1.
Change the test to do something like __proto__ = {naughty:'obj'} (cborg cli tells me it would be a1695f5f70726f746f5f5fa1676e617567687479636f626a) and then I think you have a proper test.

Other than this, it's a good change @spokodev thanks!

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