Skip to content

Commit 8cfc8b0

Browse files
aduh95ruyadorno
authored andcommitted
lib: refactor to avoid prototype pollution
PR-URL: #43474 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Juan José Arboleda <soyjuanarbol@gmail.com> Reviewed-By: Rich Trott <rtrott@gmail.com>
1 parent 7b6126a commit 8cfc8b0

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
@@ -16,6 +16,7 @@ const {
1616
ObjectFreeze,
1717
ObjectPrototypeHasOwnProperty,
1818
ObjectSetPrototypeOf,
19+
ObjectValues,
1920
Promise,
2021
ReflectApply,
2122
ReflectConstruct,
@@ -369,10 +370,15 @@ function promisify(original) {
369370
__proto__: null,
370371
value: fn, enumerable: false, writable: false, configurable: true
371372
});
372-
return ObjectDefineProperties(
373-
fn,
374-
ObjectGetOwnPropertyDescriptors(original)
375-
);
373+
374+
const descriptors = ObjectGetOwnPropertyDescriptors(original);
375+
const propertiesValues = ObjectValues(descriptors);
376+
for (let i = 0; i < propertiesValues.length; i++) {
377+
// We want to use null-prototype objects to not rely on globally mutable
378+
// %Object.prototype%.
379+
ObjectSetPrototypeOf(propertiesValues[i], null);
380+
}
381+
return ObjectDefineProperties(fn, descriptors);
376382
}
377383

378384
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;
@@ -317,6 +318,12 @@ function callbackify(original) {
317318
if (typeof descriptors.name.value === 'string') {
318319
descriptors.name.value += 'Callbackified';
319320
}
321+
const propertiesValues = ObjectValues(descriptors);
322+
for (let i = 0; i < propertiesValues.length; i++) {
323+
// We want to use null-prototype objects to not rely on globally mutable
324+
// %Object.prototype%.
325+
ObjectSetPrototypeOf(propertiesValues[i], null);
326+
}
320327
ObjectDefineProperties(callbackified, descriptors);
321328
return callbackified;
322329
}

0 commit comments

Comments
 (0)