const myData = {};
myData[rawUserInput()].key = value;
This is vulnerable if rawUserInput() returns `__proto__`: `key` on the prototype may be set to value if `myData` had `__proto__` set. If the hacker controls `key` and `value` then they can effectively modify `key` field on all objects.https://github.com/HoLyVieR/prototype-pollution-nsec18/blob/...
A common way is as described by that paper ^
Recursive merge functions, unless if they check for this vulnerability, are often susceptible, since JSON.parse defines __proto__ on its return values.
It seems that the Ghost vulnerability explained in the paper relied on the handlebars engine calling the equivalent of `eval()` on a string value, in the global scope, plus a path traversal vulnerability allowing loading a template from node_modules.
Are there are any other examples of this being exploited in a meaningful way? Even if you end up passing raw user input to key and value, user payloads will never be able to define a function, so the possibilities are very limited. I think having every NPM library that does object assignment using a user-provided key be marked as 'vulnerable to prototype pollution' is quite different from it 'being a problem very often' in practice. Happy to be shown otherwise.
Let's say your company's code is open-source, and the attacker knows there is code somewhere like this:
let state = getState(); // returns empty {} if user not authenticated
if (!state.userIsAuthenticated) {
respond(401);
}
showBankAccount();
If the hacker is able to set `Object.prototype.userIsAuthenticated` then the auth check is now bypassed.So I think the break / DDOS is pretty serious here.
You'll see prototype pollution CVEs in such libraries as jQuery, Lodash, handlebars, ajv (and transitively, request). A pretty good set of modules that are heavily used.
Scroll through the latest vunerabilities in the database and you'll see prototype pollution popping up very reliably https://snyk.io/vuln?type=npm
Is my understanding correct in saying that this is a peculiarly JavaScript issue because you can overwrite language constructs on the object prototype?
Whereas in other languages I can't affect the language core constructs?
In other languages, the data kind of object - dicts in python, hashes in ruby - allows you to associate any key with any value. In JavaScript, the hybrid kind of object that's used for both, allows you to associate keys with values, but has some keys that are special, like __proto__, that override language constructs and cause chaos and vulnerabilities.
There used to be much concern around the idea that you might load some third party js that adds thing to the base Object prototype, which will then be enumerated with for..in loops on all your data objects.
I always thought this was a stupid vulnerability because if you're executing malicious javascript, you are already screwed in a much more direct way
[Edit: i was mixing this up with a slightly different vulnerability that is a bit sillier than the one they are reffering to]
I would love to hear more on this, as it makes little sense as written. You never touch prototypes when using data objects, is the author talking about constructors pre-ES6? Or the fact you can shadow methods from the Object prototype? I don't remember seeing any exploits based on that (vs "that’s, really often, a problem").