Skip to content

Commit

Permalink
lib: refactor to avoid prototype pollution
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
aduh95 authored and juanarbol committed Oct 11, 2022
1 parent dc5478a commit a99e236
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 5 deletions.
8 changes: 8 additions & 0 deletions lib/internal/event_target.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ const {
ObjectDefineProperty,
ObjectGetOwnPropertyDescriptor,
ObjectGetOwnPropertyDescriptors,
ObjectSetPrototypeOf,
ObjectValues,
ReflectApply,
SafeArrayIterator,
SafeFinalizationRegistry,
Expand Down Expand Up @@ -1067,6 +1069,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;
};
Expand Down
14 changes: 10 additions & 4 deletions lib/internal/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ const {
ObjectFreeze,
ObjectPrototypeHasOwnProperty,
ObjectSetPrototypeOf,
ObjectValues,
Promise,
ReflectApply,
ReflectConstruct,
Expand Down Expand Up @@ -369,10 +370,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;
Expand Down
10 changes: 9 additions & 1 deletion lib/internal/worker/io.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ const {
ObjectGetOwnPropertyDescriptors,
ObjectGetPrototypeOf,
ObjectSetPrototypeOf,
ObjectValues,
ReflectApply,
Symbol,
SymbolFor,
Expand Down Expand Up @@ -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);
Expand Down
7 changes: 7 additions & 0 deletions lib/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ const {
ObjectKeys,
ObjectPrototypeToString,
ObjectSetPrototypeOf,
ObjectValues,
ReflectApply,
StringPrototypePadStart,
} = primordials;
Expand Down Expand Up @@ -317,6 +318,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;
}
Expand Down

0 comments on commit a99e236

Please sign in to comment.