Skip to content

Conversation

@ghost
Copy link

@ghost ghost commented Mar 2, 2022

Fixed issue #114 Prototype Pollution using .parse()
Please review and merge.

Copy link

@Enet4 Enet4 left a comment

Choose a reason for hiding this comment

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

I stumbled upon this by chance, but I ought to warn that this does not really fix #114. As described in the issue, the parsed output can have its prototype reassigned, which leads to the apparent surge of properties in the root object. Luckily, this seems to create new objects for the prototype every time. It does not seem to be able to pollute the prototypes of other objects.


The proposed patch never does anything, because key is always a string, so it is never equal to the global __proto__ .

The given test also passes regardless of whether the code is patched. A better set of assertions would have been the following:

var parsed = parse(xml);
assert.notEqual(parsed.length, 'polluted');
assert.notEqual(new Object().length, 'polluted');

The second assertion passes with or without the given change to the parser, since there's no real prototype pollution going on, but the first one does not. It can only pass if the implementation is adjusted to ignore the __proto__ key, thus making it not supported. With additional breaking changes to the API, an alternative is to replace dictionary objects with Maps.

Comment on lines +518 to +522
assert.deepEqual(parsed, {
__proto__: {
length: 'polluted'
}
});
Copy link

Choose a reason for hiding this comment

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

deepEqual does not test the objects' prototypes, which is why it passes. A deepStrictEqual test would fail, but we could never make it pass. A better test would check that parsed.length is not provided through the prototype chain.

Suggested change
assert.deepEqual(parsed, {
__proto__: {
length: 'polluted'
}
});
assert.notEqual(parsed.length, 'polluted');

@mreinstein
Copy link
Collaborator

resolved via #118

@mreinstein mreinstein closed this Mar 21, 2022
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.

3 participants