Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fixed Prototype Pollution using .parse() #114 #117

Closed
wants to merge 1 commit into from
Closed

fixed Prototype Pollution using .parse() #114 #117

wants to merge 1 commit into from

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.

None yet

3 participants