Skip to content

Commit a957f7b

Browse files
authored
lib: refactor to avoid prototype pollution
PR-URL: #43474 Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: Juan José Arboleda <[email protected]> Reviewed-By: Rich Trott <[email protected]>
1 parent 6dde810 commit a957f7b

File tree

4 files changed

+34
-5
lines changed

4 files changed

+34
-5
lines changed

lib/internal/event_target.js

+8
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ const {
1111
ObjectDefineProperty,
1212
ObjectGetOwnPropertyDescriptor,
1313
ObjectGetOwnPropertyDescriptors,
14+
ObjectSetPrototypeOf,
15+
ObjectValues,
1416
ReflectApply,
1517
SafeArrayIterator,
1618
SafeFinalizationRegistry,
@@ -1062,6 +1064,12 @@ const EventEmitterMixin = (Superclass) => {
10621064
}
10631065
const protoProps = ObjectGetOwnPropertyDescriptors(EventEmitter.prototype);
10641066
delete protoProps.constructor;
1067+
const propertiesValues = ObjectValues(protoProps);
1068+
for (let i = 0; i < propertiesValues.length; i++) {
1069+
// We want to use null-prototype objects to not rely on globally mutable
1070+
// %Object.prototype%.
1071+
ObjectSetPrototypeOf(propertiesValues[i], null);
1072+
}
10651073
ObjectDefineProperties(MixedEventEmitter.prototype, protoProps);
10661074
return MixedEventEmitter;
10671075
};

lib/internal/util.js

+10-4
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ const {
1717
ObjectFreeze,
1818
ObjectPrototypeHasOwnProperty,
1919
ObjectSetPrototypeOf,
20+
ObjectValues,
2021
Promise,
2122
ReflectApply,
2223
ReflectConstruct,
@@ -370,10 +371,15 @@ function promisify(original) {
370371
__proto__: null,
371372
value: fn, enumerable: false, writable: false, configurable: true
372373
});
373-
return ObjectDefineProperties(
374-
fn,
375-
ObjectGetOwnPropertyDescriptors(original)
376-
);
374+
375+
const descriptors = ObjectGetOwnPropertyDescriptors(original);
376+
const propertiesValues = ObjectValues(descriptors);
377+
for (let i = 0; i < propertiesValues.length; i++) {
378+
// We want to use null-prototype objects to not rely on globally mutable
379+
// %Object.prototype%.
380+
ObjectSetPrototypeOf(propertiesValues[i], null);
381+
}
382+
return ObjectDefineProperties(fn, descriptors);
377383
}
378384

379385
promisify.custom = kCustomPromisifiedSymbol;

lib/internal/worker/io.js

+9-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ const {
1313
ObjectGetOwnPropertyDescriptors,
1414
ObjectGetPrototypeOf,
1515
ObjectSetPrototypeOf,
16+
ObjectValues,
1617
ReflectApply,
1718
Symbol,
1819
SymbolFor,
@@ -95,10 +96,17 @@ const messageTypes = {
9596
// it inherit from NodeEventTarget, even though it is a C++ class, and b) we do
9697
// not provide methods that are not present in the Browser and not documented
9798
// on our side (e.g. stopMessagePort).
99+
const messagePortPrototypePropertyDescriptors = ObjectGetOwnPropertyDescriptors(MessagePort.prototype);
100+
const propertiesValues = ObjectValues(messagePortPrototypePropertyDescriptors);
101+
for (let i = 0; i < propertiesValues.length; i++) {
102+
// We want to use null-prototype objects to not rely on globally mutable
103+
// %Object.prototype%.
104+
ObjectSetPrototypeOf(propertiesValues[i], null);
105+
}
98106
// Save a copy of the original set of methods as a shallow clone.
99107
const MessagePortPrototype = ObjectCreate(
100108
ObjectGetPrototypeOf(MessagePort.prototype),
101-
ObjectGetOwnPropertyDescriptors(MessagePort.prototype));
109+
messagePortPrototypePropertyDescriptors);
102110
// Set up the new inheritance chain.
103111
ObjectSetPrototypeOf(MessagePort, NodeEventTarget);
104112
ObjectSetPrototypeOf(MessagePort.prototype, NodeEventTarget.prototype);

lib/util.js

+7
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ const {
4040
ObjectKeys,
4141
ObjectPrototypeToString,
4242
ObjectSetPrototypeOf,
43+
ObjectValues,
4344
ReflectApply,
4445
StringPrototypePadStart,
4546
} = primordials;
@@ -324,6 +325,12 @@ function callbackify(original) {
324325
if (typeof descriptors.name.value === 'string') {
325326
descriptors.name.value += 'Callbackified';
326327
}
328+
const propertiesValues = ObjectValues(descriptors);
329+
for (let i = 0; i < propertiesValues.length; i++) {
330+
// We want to use null-prototype objects to not rely on globally mutable
331+
// %Object.prototype%.
332+
ObjectSetPrototypeOf(propertiesValues[i], null);
333+
}
327334
ObjectDefineProperties(callbackified, descriptors);
328335
return callbackified;
329336
}

0 commit comments

Comments
 (0)