This repository aims to provide a list of JavaScript language functionality that can be affected by prototype pollution.
- Continue in the spec, currently at
Get(
18/158. - Replicate gadgets from
Object.defineProperty
withObject.defineProperties
.
The table below provides an overview of known functions affected by prototype pollution in the JavaScript language, or gadgets. This list is not exhaustive both in terms of affected APIs and usable properties.
We indicate what kind of pollution is required to use the gadgets. This helps indicate how easy it is to exploit a given gadget because data only attacks are easier in practice.
1
: Data - Gadget that work when polluting with data only.2
: Function - Gadget that require polluting with a function.3
: Function/DoS - Gadget that require polluting with a function, but polluting with a value will cause an exception.
We try to categorize the gadgets into types. These types are very subjective and mostly try to give an indication of how problematic the gadget is in terms of language design.
1
: Language - Gadgets that occur because of the language design.2
: User provided object - Gadgets that occur because a user provided object is used.3
: Faulty implementation - Gadgets that occur because a user uses an object that is implemented incorrectly.
All gadgets were tested on Node.js v22.1.0, Deno v1.37.2, Chromium v124, and Firefox v126.0.
API | Prop(s) | Level | Type | Node.js | Deno | Chromium | Firefox |
---|---|---|---|---|---|---|---|
[[OwnPropertyKeys]] |
<n> |
1 |
3 |
Yes | Yes | Yes | Yes |
[[ToPrimitive]] |
toString |
3 |
1 |
Yes | Yes | Yes | Yes |
valueOf |
2 |
1 |
Yes | Yes | Yes | Yes | |
new ArrayBuffer |
maxByteLength |
1 |
2 |
Yes | Yes | Yes | No |
Function.prototype.apply |
<n> |
1 |
3 |
Yes | Yes | Yes | Yes |
Iterator |
next |
3 |
3 |
Yes | Yes | Yes | Yes |
JSON.stringify |
toObject |
2 |
1 |
Yes | Yes | Yes | Yes |
Object.defineProperty |
configurable |
1 |
2 |
Yes | Yes | Yes | Yes |
enumerable |
1 |
2 |
Yes | Yes | Yes | Yes | |
get |
3 |
2 |
Yes | Yes | Yes | Yes | |
set |
3 |
2 |
Yes | Yes | Yes | Yes | |
value |
1 |
2 |
Yes | Yes | Yes | Yes | |
writable |
1 |
2 |
Yes | Yes | Yes | Yes | |
Object.entries |
enumerable |
1 |
3 |
Yes | Yes | Yes | Yes |
Object.fromEntries |
0,1 |
1 |
1 |
Yes | Yes | Yes | Yes |
Object.keys |
enumerable |
1 |
3 |
Yes | Yes | Yes | Yes |
Object.values |
enumerable |
1 |
3 |
Yes | Yes | Yes | Yes |
Reflect.apply |
<n> |
1 |
3 |
Yes | Yes | Yes | Yes |
Reflect.construct |
<n> |
1 |
3 |
Yes | Yes | Yes | Yes |
new SharedArrayBuffer |
maxByteLength |
1 |
2 |
Yes | Yes | Unsupported | Unsupported |
String.prototype.endsWith |
@@match |
1 |
2 |
Yes | Yes | Yes | Yes |
String.prototype.includes |
@@match |
1 |
2 |
Yes | Yes | Yes | Yes |
String.prototype.matchAll |
@@match,@@matchAll,flags |
3 |
2 |
Yes | Yes | Yes | Yes |
String.prototype.replaceAll |
@@match,@@replace,flags |
3 |
2 |
Yes | Yes | Yes | Yes |
String.prototype.startsWith |
@@match |
1 |
2 |
Yes | Yes | Yes | Yes |
The table below lists evaluated sections in the ECMAScript spec which were deemed unaffected by prototype pollution.
API | Property | Reason |
---|---|---|
CopyDataProperties |
<key> |
Implementation should ToObject the subject, hence all own keys are actually own keys. |
OrdinaryHasInstance |
prototype |
Object on which lookup should happen must be a callable, which means it must have a prototype property. |
So far this overview has been created manually by inspecting the ECMAScript spec
looking for use of the Get(O, P)
function. This function gets property P
from object O
, hence if P
is missing from O
the lookup could be affected
by prototype pollution.
Additionally, during testing a proxy object like the one shown below is used to find out what properties are being looked up exactly.
const proxy = new Proxy({}, {
get(target, property, _receiver) {
if (!Object.hasOwn(target, property)) {
console.log("looked up:", property);
}
return target[property];
},
});
-
Silent Spring: Prototype Pollution Leads to Remote Code Execution in Node.js
Toolchain to find prototype pollution and gadgets in libraries and the Node.js runtime. It cannot find the gadgets described in this repository because the it cannot statically analyze built-in functionality.