lib: refactor to avoid prototype pollution

PR-URL: https://github.com/nodejs/node/pull/43474
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Juan José Arboleda <soyjuanarbol@gmail.com>
Reviewed-By: Rich Trott <rtrott@gmail.com>
This commit is contained in:
Antoine du Hamel 2022-08-17 20:36:33 +02:00 committed by GitHub
parent 6dde81042f
commit a957f7bd37
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 34 additions and 5 deletions

View File

@ -11,6 +11,8 @@ const {
ObjectDefineProperty,
ObjectGetOwnPropertyDescriptor,
ObjectGetOwnPropertyDescriptors,
ObjectSetPrototypeOf,
ObjectValues,
ReflectApply,
SafeArrayIterator,
SafeFinalizationRegistry,
@ -1062,6 +1064,12 @@ const EventEmitterMixin = (Superclass) => {
}
const protoProps = ObjectGetOwnPropertyDescriptors(EventEmitter.prototype);
delete protoProps.constructor;
const propertiesValues = ObjectValues(protoProps);
for (let i = 0; i < propertiesValues.length; i++) {
// We want to use null-prototype objects to not rely on globally mutable
// %Object.prototype%.
ObjectSetPrototypeOf(propertiesValues[i], null);
}
ObjectDefineProperties(MixedEventEmitter.prototype, protoProps);
return MixedEventEmitter;
};

View File

@ -17,6 +17,7 @@ const {
ObjectFreeze,
ObjectPrototypeHasOwnProperty,
ObjectSetPrototypeOf,
ObjectValues,
Promise,
ReflectApply,
ReflectConstruct,
@ -370,10 +371,15 @@ function promisify(original) {
__proto__: null,
value: fn, enumerable: false, writable: false, configurable: true
});
return ObjectDefineProperties(
fn,
ObjectGetOwnPropertyDescriptors(original)
);
const descriptors = ObjectGetOwnPropertyDescriptors(original);
const propertiesValues = ObjectValues(descriptors);
for (let i = 0; i < propertiesValues.length; i++) {
// We want to use null-prototype objects to not rely on globally mutable
// %Object.prototype%.
ObjectSetPrototypeOf(propertiesValues[i], null);
}
return ObjectDefineProperties(fn, descriptors);
}
promisify.custom = kCustomPromisifiedSymbol;

View File

@ -13,6 +13,7 @@ const {
ObjectGetOwnPropertyDescriptors,
ObjectGetPrototypeOf,
ObjectSetPrototypeOf,
ObjectValues,
ReflectApply,
Symbol,
SymbolFor,
@ -95,10 +96,17 @@ const messageTypes = {
// it inherit from NodeEventTarget, even though it is a C++ class, and b) we do
// not provide methods that are not present in the Browser and not documented
// on our side (e.g. stopMessagePort).
const messagePortPrototypePropertyDescriptors = ObjectGetOwnPropertyDescriptors(MessagePort.prototype);
const propertiesValues = ObjectValues(messagePortPrototypePropertyDescriptors);
for (let i = 0; i < propertiesValues.length; i++) {
// We want to use null-prototype objects to not rely on globally mutable
// %Object.prototype%.
ObjectSetPrototypeOf(propertiesValues[i], null);
}
// Save a copy of the original set of methods as a shallow clone.
const MessagePortPrototype = ObjectCreate(
ObjectGetPrototypeOf(MessagePort.prototype),
ObjectGetOwnPropertyDescriptors(MessagePort.prototype));
messagePortPrototypePropertyDescriptors);
// Set up the new inheritance chain.
ObjectSetPrototypeOf(MessagePort, NodeEventTarget);
ObjectSetPrototypeOf(MessagePort.prototype, NodeEventTarget.prototype);

View File

@ -40,6 +40,7 @@ const {
ObjectKeys,
ObjectPrototypeToString,
ObjectSetPrototypeOf,
ObjectValues,
ReflectApply,
StringPrototypePadStart,
} = primordials;
@ -324,6 +325,12 @@ function callbackify(original) {
if (typeof descriptors.name.value === 'string') {
descriptors.name.value += 'Callbackified';
}
const propertiesValues = ObjectValues(descriptors);
for (let i = 0; i < propertiesValues.length; i++) {
// We want to use null-prototype objects to not rely on globally mutable
// %Object.prototype%.
ObjectSetPrototypeOf(propertiesValues[i], null);
}
ObjectDefineProperties(callbackified, descriptors);
return callbackified;
}