/pp-runtime-gadgets

Gadgets in the JavaScript runtime based on the ECMAScript specification

Primary LanguageJavaScript

Prototype Pollution affects the JavaScript Runtime

This repository aims to provide a list of JavaScript language functionality that can be affected by prototype pollution.

TODO

  • Continue in the spec, currently at Get( 18/158.
  • Replicate gadgets from Object.defineProperty with Object.defineProperties.

Overview

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

Unaffected

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.

Approach

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];
  },
});

Related Work