4 ms·
Prototype Pollution (2020)
- rectang 5y agoI remember "prototype pollution" as the annoying result of monkeypatching a la prototype.js way back when. But this article presents prototype pollution as a security issue. If an attacker can perform "prototype pollution", aren't they already injecting arbitrary JavaScript into the page? If they already have script injection, why would they choose "prototype pollution" over anything else they could do with arbitrary code?
- furstenheim 5y agoThis article is not very good in convincing that prototype pollution is a problem. There was a write up about the kibana rce that really shows it's a problem: https://research.securitum.com/prototype-pollution-rce-kibana-cve-2019-7609/ https://research.securitum.com/prototype-pollution-rce-kiban...
- ble 5y agoThanks for the link, this is a much clearer example of how prototype pollution can be an important vector. As another commenter noted, if one can directly inject literal JS code that writes to __proto__, you've already got RCE. The case where prototype pollution happens without arbitrary RCE looks like: - User input can set arbitrary fields of an object and its properties, allowing the user to add or alter a field on a `__proto__` that references a widely-shared prototype; - The existence or value of that field non-locally affects other code which assumes that the prototype is not under user control.
- valand 5y agoOne I can think of: AFAIK An arbitraty JavaScript cannot access values declared out of its scope. Prototype pollution add a capability of an attacker introduce a hook-like mechanism to intercept values passed via an object's method.
- mattigames 5y agoIn some specific scenarios an attacker can perform prototype manipulation without being able to inject arbitrary code, in this jquery bug you can see one such case due faulty parsing of a json object (json that may come from untrusted sources) https://snyk.io/blog/after-three-years-of-silence-a-new-jquery-prototype-pollution-vulnerability-emerges-once-again/ https://snyk.io/blog/after-three-years-of-silence-a-new-jque...
- mediumdeviation 5y agoThe most common vulnerability that grants RCE has the attacker exploiting poorly designed deserialization code. Those are high impact but not too common since deserialization is hopefully closely scrutinised. There are other problems that naturally fall out of the fact that by default all objects, including those from JSON.parse, inherit the Object prototype though. For example - - If you store user membership or permission as an object with some user controlled identifier (eg. a username) as key, then check if a user is permitted at all with `username in permissions`, a user can name themselves hasOwnProperty to bypass the check since it is part of the Object prototype - If you deserialize some JSON then try to check membership with `o.hasOwnProperty(someKey)`, a malicious user can pass in JSON with hasOwnProperty as key. This will crash since hasOwnProperty is no longer a function on the object. These are not necessarily common, but it’s annoying how easy it is for these to slip through. The object prototype in general is just a massive footgun
- airza 5y agoI have seen a lot of attacks using it on the server side, like: -innocuous looking code merges user supplied input from a json object ("we just use this to render a view or write it to an object store") -attacker throws in a __proto__ property which means every object in the _entire_ node runtime has that value for that key until it's overwritten in script -random templating engine has a config option that would _never_ be controlled by an attacker, right? -oops, RCE!
- fmdjeksnc 5y agoYou can also easily cause DOS by overwriting toString to return something unexpected like an int
- deleted 5y ago[deleted]
- NicolaiS 5y agoImagine you have a game with attacker controlled (x, y): var { x, y } = JSON.parse(input); board[x][y] = true; // ... if (user.admin) ... If the attacker puts: {x: "__proto__", y: "admin"} Then board["__proto__"] might be `object` and then object["admin"] = true Now `<any object>.admin` is true !
- andreareina 5y agoHow is this different from monkeypatching in e.g. Python, Ruby?
- dragonwriter 5y ago> How is this different from monkeypatching in e.g. Python, Ruby? It’s not monkeypatching, its a class of vilnerabilities that allow an attacker to do the monkeypatching, and to do so to the root Object. Key things about JavaScript that differ from Ruby/Python relevant to it are: (1) Prototype-based inheritance, (2) Syntax and common idioms thar support and encourage use of plain objects where Ruby/Python would use string-keyed Hash/dict instances (equivalent to JS Map), including when objects are constructed from untrusted JSON (which, again, Ruby/Python would serialize to Hash/dict, not exposing member properties ot manipulation). What would be reading a Hash/dict keyvalue pair from an untrusted source in Ruby or Python (not, generally, risky) can easily be, in JavaScript, opening a gateway to potentiallt inject data members to the shared prototype of all objects.