New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

vm2

Package Overview
Dependencies
Maintainers
2
Versions
65
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

vm2 - npm Package Compare versions

Comparing version

to
3.6.7

952

lib/contextify.js

@@ -8,4 +8,7 @@ /* global host */

const global = this;
const local = {Object};
const local = host.Object.create(null);
local.Object = Object;
local.Reflect = Reflect;
// global is originally prototype of host.Object so it can be used to climb up from the sandbox.

@@ -24,11 +27,11 @@ Object.setPrototypeOf(global, Object.prototype);

const captureStackTrace = Error.captureStackTrace;
const FROZEN_TRAPS = {
set: (target, key) => false,
setPrototypeOf: (target, key) => false,
defineProperty: (target, key) => false,
deleteProperty: (target, key) => false,
isExtensible: (target, key) => false,
preventExtensions: (target) => false
};
const FROZEN_TRAPS = host.Object.create(null);
FROZEN_TRAPS.set = (target, key) => false;
FROZEN_TRAPS.setPrototypeOf = (target, key) => false;
FROZEN_TRAPS.defineProperty = (target, key) => false;
FROZEN_TRAPS.deleteProperty = (target, key) => false;
FROZEN_TRAPS.isExtensible = (target, key) => false;
FROZEN_TRAPS.preventExtensions = (target) => false;
// Map of contextified objects to original objects

@@ -51,2 +54,7 @@ const Contextified = new host.WeakMap();

const hasInstance = Object[Symbol.hasInstance];
function instanceOf(value, construct) {
return hasInstance.call(construct, value);
}
/**

@@ -73,218 +81,274 @@ * VMError definition.

const Decontextify = {
proxies: new host.WeakMap(),
const Decontextify = host.Object.create(null);
Decontextify.proxies = new host.WeakMap();
arguments: args => {
if (!host.Array.isArray(args)) return new host.Array();
Decontextify.arguments = args => {
if (!host.Array.isArray(args)) return new host.Array();
const arr = new host.Array();
for (let i = 0, l = args.length; i < l; i++) arr[i] = Decontextify.value(args[i]);
return arr;
},
instance: (instance, klass, deepTraps, flags) => {
return Decontextify.object(instance, {
get: (target, key, receiver) => {
if (key === 'vmProxyTarget' && DEBUG) return instance;
if (key === 'isVMProxy') return true;
if (key === 'constructor') return klass;
if (key === '__proto__') return klass.prototype;
if (key === '__defineGetter__') return fakeDefineGetter(receiver);
if (key === '__defineSetter__') return fakeDefineSetter(receiver);
const arr = new host.Array();
for (let i = 0, l = args.length; i < l; i++) arr[i] = Decontextify.value(args[i]);
return arr;
};
Decontextify.instance = (instance, klass, deepTraps, flags) => {
if (typeof instance === 'function') return Decontextify.function(instance);
try {
return Decontextify.value(instance[key], null, deepTraps, flags);
} catch (e) {
throw Decontextify.value(e);
}
},
getPrototypeOf: (target) => {
return klass.prototype;
}
}, deepTraps, flags);
},
function: (fnc, traps, deepTraps, flags, mock) => {
const self = Decontextify.object(fnc, host.Object.assign({
apply: (target, context, args) => {
try {
context = Contextify.value(context);
// We must not use normal object because there's a chance object already contains malicious code in the prototype
const base = host.Object.create(null);
// Set context of all arguments to vm's context.
return Decontextify.value(fnc.apply(context, Contextify.arguments(args)));
} catch (e) {
throw Decontextify.value(e);
}
},
construct: (target, args, newTarget) => {
try {
return Decontextify.instance(new fnc(...Contextify.arguments(args)), self, deepTraps, flags);
} catch (e) {
throw Decontextify.value(e);
}
},
get: (target, key, receiver) => {
if (key === 'vmProxyTarget' && DEBUG) return fnc;
if (key === 'isVMProxy') return true;
if (mock && host.Object.prototype.hasOwnProperty.call(mock, key)) return mock[key];
if (key === 'constructor') return host.Function;
if (key === '__proto__') return host.Function.prototype;
if (key === '__defineGetter__') return fakeDefineGetter(receiver);
if (key === '__defineSetter__') return fakeDefineSetter(receiver);
base.get = (target, key, receiver) => {
if (key === 'vmProxyTarget' && DEBUG) return instance;
if (key === 'isVMProxy') return true;
if (key === 'constructor') return klass;
if (key === '__proto__') return klass.prototype;
if (key === '__defineGetter__') return fakeDefineGetter(receiver);
if (key === '__defineSetter__') return fakeDefineSetter(receiver);
try {
return Decontextify.value(fnc[key], null, deepTraps, flags);
} catch (e) {
throw Decontextify.value(e);
}
},
getPrototypeOf: (target) => {
return host.Function.prototype;
}
}, traps), deepTraps);
try {
return Decontextify.value(instance[key], null, deepTraps, flags);
} catch (e) {
throw Decontextify.value(e);
}
};
base.getPrototypeOf = (target) => {
return klass && klass.prototype;
};
return self;
},
object: (object, traps, deepTraps, flags, mock) => {
const proxy = new host.Proxy(object, host.Object.assign({
get: (target, key, receiver) => {
if (key === 'vmProxyTarget' && DEBUG) return object;
if (key === 'isVMProxy') return true;
if (mock && host.Object.prototype.hasOwnProperty.call(mock, key)) return mock[key];
if (key === 'constructor') return host.Object;
if (key === '__proto__') return host.Object.prototype;
if (key === '__defineGetter__') return fakeDefineGetter(receiver);
if (key === '__defineSetter__') return fakeDefineSetter(receiver);
return Decontextify.object(instance, base, deepTraps, flags);
};
Decontextify.function = (fnc, traps, deepTraps, flags, mock) => {
// We must not use normal object because there's a chance object already contains malicious code in the prototype
const base = host.Object.create(null);
let proxy;
try {
return Decontextify.value(object[key], null, deepTraps, flags);
} catch (e) {
throw Decontextify.value(e);
}
},
set: (target, key, value, receiver) => {
try {
object[key] = Contextify.value(value);
return true;
} catch (e) {
throw Decontextify.value(e);
}
},
getOwnPropertyDescriptor: (target, prop) => {
let def;
base.apply = (target, context, args) => {
try {
context = Contextify.value(context);
try {
def = host.Object.getOwnPropertyDescriptor(object, prop);
} catch (e) {
throw Decontextify.value(e);
}
// Set context of all arguments to vm's context.
return Decontextify.value(fnc.apply(context, Contextify.arguments(args)));
} catch (e) {
throw Decontextify.value(e);
}
};
base.construct = (target, args, newTarget) => {
try {
return Decontextify.instance(new fnc(...Contextify.arguments(args)), proxy, deepTraps, flags);
} catch (e) {
throw Decontextify.value(e);
}
};
base.get = (target, key, receiver) => {
if (key === 'vmProxyTarget' && DEBUG) return fnc;
if (key === 'isVMProxy') return true;
if (mock && host.Object.prototype.hasOwnProperty.call(mock, key)) return mock[key];
if (key === 'constructor') return host.Function;
if (key === '__proto__') return host.Function.prototype;
if (key === '__defineGetter__') return fakeDefineGetter(receiver);
if (key === '__defineSetter__') return fakeDefineSetter(receiver);
// Following code prevents V8 to throw
// TypeError: 'getOwnPropertyDescriptor' on proxy: trap reported non-configurability for property '<prop>'
// which is either non-existant or configurable in the proxy target
try {
return Decontextify.value(fnc[key], null, deepTraps, flags);
} catch (e) {
throw Decontextify.value(e);
}
};
base.getPrototypeOf = (target) => {
return host.Function.prototype;
};
if (!def) {
return undefined;
} else if (def.get || def.set) {
return {
get: Decontextify.value(def.get) || undefined,
set: Decontextify.value(def.set) || undefined,
enumerable: def.enumerable === true,
configurable: def.configurable === true
};
} else {
return {
value: Decontextify.value(def.value),
writable: def.writable === true,
enumerable: def.enumerable === true,
configurable: def.configurable === true
};
}
},
defineProperty: (target, key, descriptor) => {
try {
if (descriptor.get || descriptor.set) {
return host.Object.defineProperty(target, key, {
get: Contextify.value(descriptor.get, null, deepTraps, flags) || undefined,
set: Contextify.value(descriptor.set, null, deepTraps, flags) || undefined,
enumerable: descriptor.enumerable === true,
configurable: descriptor.configurable === true
});
} else {
return host.Object.defineProperty(target, key, {
value: Contextify.value(descriptor.value, null, deepTraps, flags),
writable: descriptor.writable === true,
enumerable: descriptor.enumerable === true,
configurable: descriptor.configurable === true
});
}
} catch (e) {
throw Decontextify.value(e);
}
},
getPrototypeOf: (target) => {
return host.Object.prototype;
},
setPrototypeOf: (target) => {
throw new host.Error(OPNA);
}
}, traps, deepTraps));
proxy = Decontextify.object(fnc, host.Object.assign(base, traps), deepTraps);
return proxy;
};
Decontextify.object = (object, traps, deepTraps, flags, mock) => {
// We must not use normal object because there's a chance object already contains malicious code in the prototype
const base = host.Object.create(null);
Decontextify.proxies.set(object, proxy);
Decontextified.set(proxy, object);
return proxy;
},
value: (value, traps, deepTraps, flags, mock) => {
if (Contextified.has(value)) {
// Contextified object has returned back from vm
return Contextified.get(value);
} else if (Decontextify.proxies.has(value)) {
// Decontextified proxy already exists, reuse
return Decontextify.proxies.get(value);
base.get = (target, key, receiver) => {
if (key === 'vmProxyTarget' && DEBUG) return object;
if (key === 'isVMProxy') return true;
if (mock && host.Object.prototype.hasOwnProperty.call(mock, key)) return mock[key];
if (key === 'constructor') return host.Object;
if (key === '__proto__') return host.Object.prototype;
if (key === '__defineGetter__') return fakeDefineGetter(receiver);
if (key === '__defineSetter__') return fakeDefineSetter(receiver);
try {
return Decontextify.value(object[key], null, deepTraps, flags);
} catch (e) {
throw Decontextify.value(e);
}
};
base.set = (target, key, value, receiver) => {
try {
object[key] = Contextify.value(value);
return true;
} catch (e) {
throw Decontextify.value(e);
}
};
base.getOwnPropertyDescriptor = (target, prop) => {
let def;
try {
// If for some reason we get already decontextified value, get out.
// Decontextifying already decontextified value breaks the security.
if (value instanceof host.Object) return value;
def = host.Object.getOwnPropertyDescriptor(object, prop);
} catch (e) {
throw new VMError('Failed to decontextify object.');
throw Decontextify.value(e);
}
switch (typeof value) {
case 'object':
try {
if (value === null) {
return null;
} else if (value instanceof Number) { return host.Number(value);
} else if (value instanceof String) { return host.String(value);
} else if (value instanceof Boolean) { return host.Boolean(value);
} else if (value instanceof Date) { return Decontextify.instance(value, host.Date, deepTraps, flags);
} else if (value instanceof RangeError) { return Decontextify.instance(value, host.RangeError, deepTraps, flags);
} else if (value instanceof ReferenceError) { return Decontextify.instance(value, host.ReferenceError, deepTraps, flags);
} else if (value instanceof SyntaxError) { return Decontextify.instance(value, host.SyntaxError, deepTraps, flags);
} else if (value instanceof TypeError) { return Decontextify.instance(value, host.TypeError, deepTraps, flags);
} else if (value instanceof VMError) { return Decontextify.instance(value, host.VMError, deepTraps, flags);
} else if (value instanceof Error) { return Decontextify.instance(value, host.Error, deepTraps, flags);
} else if (value instanceof Array) { return Decontextify.instance(value, host.Array, deepTraps, flags);
} else if (value instanceof RegExp) { return Decontextify.instance(value, host.RegExp, deepTraps, flags);
} else if (value instanceof Map) { return Decontextify.instance(value, host.Map, deepTraps, flags);
} else if (value instanceof WeakMap) { return Decontextify.instance(value, host.WeakMap, deepTraps, flags);
} else if (value instanceof Set) { return Decontextify.instance(value, host.Set, deepTraps, flags);
} else if (value instanceof WeakSet) { return Decontextify.instance(value, host.WeakSet, deepTraps, flags);
} else if (Promise && value instanceof Promise) { return Decontextify.instance(value, host.Promise, deepTraps, flags);
} else {
return Decontextify.object(value, traps, deepTraps, flags, mock);
}
} catch (e) {
throw Decontextify.value(e);
}
case 'function':
return Decontextify.function(value, traps, deepTraps, flags, mock);
// Following code prevents V8 to throw
// TypeError: 'getOwnPropertyDescriptor' on proxy: trap reported non-configurability for property '<prop>'
// which is either non-existant or configurable in the proxy target
case 'undefined':
return undefined;
if (!def) {
return undefined;
} else if (def.get || def.set) {
return {
get: Decontextify.value(def.get) || undefined,
set: Decontextify.value(def.set) || undefined,
enumerable: def.enumerable === true,
configurable: def.configurable === true
};
} else {
return {
value: Decontextify.value(def.value),
writable: def.writable === true,
enumerable: def.enumerable === true,
configurable: def.configurable === true
};
}
};
base.defineProperty = (target, key, descriptor) => {
// There's a chance accessing a property throws an error so we must not access them
// in try catch to prevent contextyfing local objects.
const getter = Contextify.value(descriptor.get, null, deepTraps, flags);
const setter = Contextify.value(descriptor.set, null, deepTraps, flags);
const valuer = Contextify.value(descriptor.value, null, deepTraps, flags);
const enumerable = descriptor.enumerable === true;
const configurable = descriptor.configurable === true;
const writable = descriptor.writable === true;
default: // string, number, boolean, symbol
return value;
try {
if (getter || setter) {
return host.Object.defineProperty(target, key, {
get: getter || undefined,
set: setter || undefined,
enumerable: enumerable,
configurable: configurable
});
} else {
return host.Object.defineProperty(target, key, {
value: valuer,
writable: writable,
enumerable: enumerable,
configurable: configurable
});
}
} catch (e) {
throw Decontextify.value(e);
}
};
base.getPrototypeOf = (target) => {
return host.Object.prototype;
};
base.setPrototypeOf = (target) => {
throw new host.Error(OPNA);
};
base.has = (target, key) => {
try {
return key in object;
} catch (e) {
throw Decontextify.value(e);
}
};
base.isExtensible = target => {
try {
return Decontextify.value(local.Object.isExtensible(object));
} catch (e) {
throw Decontextify.value(e);
}
};
base.ownKeys = target => {
try {
return Decontextify.value(local.Reflect.ownKeys(object));
} catch (e) {
throw Decontextify.value(e);
}
};
base.preventExtensions = target => {
try {
local.Object.preventExtensions(object);
return true;
} catch (e) {
throw Decontextify.value(e);
}
};
base.enumerate = target => {
try {
return Decontextify.value(local.Reflect.enumerate(object));
} catch (e) {
throw Decontextify.value(e);
}
};
const proxy = new host.Proxy(object, host.Object.assign(base, traps, deepTraps));
Decontextify.proxies.set(object, proxy);
Decontextified.set(proxy, object);
return proxy;
};
Decontextify.value = (value, traps, deepTraps, flags, mock) => {
if (Contextified.has(value)) {
// Contextified object has returned back from vm
return Contextified.get(value);
} else if (Decontextify.proxies.has(value)) {
// Decontextified proxy already exists, reuse
return Decontextify.proxies.get(value);
}
try {
// If for some reason we get already scoped value, get out.
// Decontextifying already scoped value breaks the security.
if (instanceOf(value, host.Object)) return value;
} catch (e) {
throw new VMError('Failed to decontextify object.');
}
switch (typeof value) {
case 'object':
try {
if (value === null) {
return null;
} else if (instanceOf(value, Number)) { return host.Number(value);
} else if (instanceOf(value, String)) { return host.String(value);
} else if (instanceOf(value, Boolean)) { return host.Boolean(value);
} else if (instanceOf(value, Date)) { return Decontextify.instance(value, host.Date, deepTraps, flags);
} else if (instanceOf(value, RangeError)) { return Decontextify.instance(value, host.RangeError, deepTraps, flags);
} else if (instanceOf(value, ReferenceError)) { return Decontextify.instance(value, host.ReferenceError, deepTraps, flags);
} else if (instanceOf(value, SyntaxError)) { return Decontextify.instance(value, host.SyntaxError, deepTraps, flags);
} else if (instanceOf(value, TypeError)) { return Decontextify.instance(value, host.TypeError, deepTraps, flags);
} else if (instanceOf(value, VMError)) { return Decontextify.instance(value, host.VMError, deepTraps, flags);
} else if (instanceOf(value, Error)) { return Decontextify.instance(value, host.Error, deepTraps, flags);
} else if (instanceOf(value, Array)) { return Decontextify.instance(value, host.Array, deepTraps, flags);
} else if (instanceOf(value, RegExp)) { return Decontextify.instance(value, host.RegExp, deepTraps, flags);
} else if (instanceOf(value, Map)) { return Decontextify.instance(value, host.Map, deepTraps, flags);
} else if (instanceOf(value, WeakMap)) { return Decontextify.instance(value, host.WeakMap, deepTraps, flags);
} else if (instanceOf(value, Set)) { return Decontextify.instance(value, host.Set, deepTraps, flags);
} else if (instanceOf(value, WeakSet)) { return Decontextify.instance(value, host.WeakSet, deepTraps, flags);
} else if (Promise && instanceOf(value, Promise)) { return Decontextify.instance(value, host.Promise, deepTraps, flags);
} else if (host.Object.getPrototypeOf(value) === null) {
return Decontextify.instance(value, null, deepTraps, flags);
} else {
return Decontextify.object(value, traps, deepTraps, flags, mock);
}
} catch (e) {
throw Decontextify.value(e);
}
case 'function':
return Decontextify.function(value, traps, deepTraps, flags, mock);
case 'undefined':
return undefined;
default: // string, number, boolean, symbol
return value;
}
};

@@ -296,238 +360,296 @@

const Contextify = {
proxies: new host.WeakMap(),
const Contextify = host.Object.create(null);
Contextify.proxies = new host.WeakMap();
arguments: args => {
if (!host.Array.isArray(args)) return new Array();
Contextify.arguments = args => {
if (!host.Array.isArray(args)) return new Array();
const arr = new Array();
for (let i = 0, l = args.length; i < l; i++) arr[i] = Contextify.value(args[i]);
return arr;
},
instance: (instance, klass, deepTraps, flags) => {
return Contextify.object(instance, {
get: (target, key, receiver) => {
if (key === 'vmProxyTarget' && DEBUG) return instance;
if (key === 'isVMProxy') return true;
if (key === 'constructor') return klass;
if (key === '__proto__') return klass.prototype;
if (key === '__defineGetter__') return fakeDefineGetter(receiver, true);
if (key === '__defineSetter__') return fakeDefineSetter(receiver, true);
const arr = new Array();
for (let i = 0, l = args.length; i < l; i++) arr[i] = Contextify.value(args[i]);
return arr;
};
Contextify.instance = (instance, klass, deepTraps, flags) => {
if (typeof instance === 'function') return Contextify.function(instance);
try {
return Contextify.value(instance[key], null, deepTraps, flags);
} catch (e) {
throw Contextify.value(e);
}
},
getPrototypeOf: (target) => {
return klass.prototype;
}
}, deepTraps, flags);
},
function: (fnc, traps, deepTraps, flags, mock) => {
const self = Contextify.object(fnc, host.Object.assign({
apply: (target, context, args) => {
try {
context = Decontextify.value(context);
// We must not use normal object because there's a chance object already contains malicious code in the prototype
const base = host.Object.create(null);
// Set context of all arguments to host's context.
return Contextify.value(fnc.apply(context, Decontextify.arguments(args)));
} catch (e) {
throw Contextify.value(e);
}
},
construct: (target, args, newTarget) => {
// Fixes buffer unsafe allocation for node v6/7
if (host.version < 8 && fnc === host.Buffer && 'number' === typeof args[0]) {
args[0] = new Array(args[0]).fill(0);
}
base.get = (target, key, receiver) => {
if (key === 'vmProxyTarget' && DEBUG) return instance;
if (key === 'isVMProxy') return true;
if (key === 'constructor') return klass;
if (key === '__proto__') return klass.prototype;
if (key === '__defineGetter__') return fakeDefineGetter(receiver, true);
if (key === '__defineSetter__') return fakeDefineSetter(receiver, true);
try {
return Contextify.instance(new fnc(...Decontextify.arguments(args)), self, deepTraps, flags);
} catch (e) {
throw Contextify.value(e);
}
},
get: (target, key, receiver) => {
if (key === 'vmProxyTarget' && DEBUG) return fnc;
if (key === 'isVMProxy') return true;
if (mock && host.Object.prototype.hasOwnProperty.call(mock, key)) return mock[key];
if (key === 'constructor') return Function;
if (key === '__proto__') return Function.prototype;
if (key === '__defineGetter__') return fakeDefineGetter(receiver, true);
if (key === '__defineSetter__') return fakeDefineSetter(receiver, true);
try {
return Contextify.value(instance[key], null, deepTraps, flags);
} catch (e) {
throw Contextify.value(e);
}
};
base.getPrototypeOf = (target) => {
return klass && klass.prototype;
};
try {
return Contextify.value(fnc[key], null, deepTraps, flags);
} catch (e) {
throw Contextify.value(e);
}
},
getPrototypeOf: (target) => {
return Function.prototype;
}
}, traps), deepTraps);
return Contextify.object(instance, base, deepTraps, flags);
};
Contextify.function = (fnc, traps, deepTraps, flags, mock) => {
// We must not use normal object because there's a chance object already contains malicious code in the prototype
const base = host.Object.create(null);
let proxy;
return self;
},
object: (object, traps, deepTraps, flags, mock) => {
const proxy = new host.Proxy(object, host.Object.assign({
get: (target, key, receiver) => {
if (key === 'vmProxyTarget' && DEBUG) return object;
if (key === 'isVMProxy') return true;
if (mock && host.Object.prototype.hasOwnProperty.call(mock, key)) return mock[key];
if (key === 'constructor') return Object;
if (key === '__proto__') return Object.prototype;
if (key === '__defineGetter__') return fakeDefineGetter(receiver, true);
if (key === '__defineSetter__') return fakeDefineSetter(receiver, true);
base.apply = (target, context, args) => {
try {
context = Decontextify.value(context);
try {
return Contextify.value(object[key], null, deepTraps, flags);
} catch (e) {
throw Contextify.value(e);
}
},
set: (target, key, value, receiver) => {
if (flags && flags.protected && typeof value === 'function') return false;
// Set context of all arguments to host's context.
return Contextify.value(fnc.apply(context, Decontextify.arguments(args)));
} catch (e) {
throw Contextify.value(e);
}
};
base.construct = (target, args, newTarget) => {
// Fixes buffer unsafe allocation for node v6/7
if (host.version < 8 && fnc === host.Buffer && 'number' === typeof args[0]) {
args[0] = new Array(args[0]).fill(0);
}
try {
object[key] = Decontextify.value(value);
return true;
} catch (e) {
throw Contextify.value(e);
}
},
getOwnPropertyDescriptor: (target, prop) => {
let def;
try {
return Contextify.instance(new fnc(...Decontextify.arguments(args)), proxy, deepTraps, flags);
} catch (e) {
throw Contextify.value(e);
}
};
base.get = (target, key, receiver) => {
if (key === 'vmProxyTarget' && DEBUG) return fnc;
if (key === 'isVMProxy') return true;
if (mock && host.Object.prototype.hasOwnProperty.call(mock, key)) return mock[key];
if (key === 'constructor') return Function;
if (key === '__proto__') return Function.prototype;
if (key === '__defineGetter__') return fakeDefineGetter(receiver, true);
if (key === '__defineSetter__') return fakeDefineSetter(receiver, true);
try {
def = host.Object.getOwnPropertyDescriptor(object, prop);
} catch (e) {
throw Contextify.value(e);
}
try {
return Contextify.value(fnc[key], null, deepTraps, flags);
} catch (e) {
throw Contextify.value(e);
}
};
base.getPrototypeOf = (target) => {
return Function.prototype;
};
// Following code prevents V8 to throw
// TypeError: 'getOwnPropertyDescriptor' on proxy: trap reported non-configurability for property '<prop>'
// which is either non-existant or configurable in the proxy target
proxy = Contextify.object(fnc, host.Object.assign(base, traps), deepTraps);
return proxy;
};
Contextify.object = (object, traps, deepTraps, flags, mock) => {
// We must not use normal object because there's a chance object already contains malicious code in the prototype
const base = host.Object.create(null);
if (!def) {
return undefined;
} else if (def.get || def.set) {
return {
get: Contextify.value(def.get, null, deepTraps, flags) || undefined,
set: Contextify.value(def.set, null, deepTraps, flags) || undefined,
enumerable: def.enumerable === true,
configurable: def.configurable === true
};
} else {
return {
value: Contextify.value(def.value, null, deepTraps, flags),
writable: def.writable === true,
enumerable: def.enumerable === true,
configurable: def.configurable === true
};
}
},
defineProperty: (target, key, descriptor) => {
if (flags && flags.protected && typeof descriptor.value === 'function') return false;
base.get = (target, key, receiver) => {
if (key === 'vmProxyTarget' && DEBUG) return object;
if (key === 'isVMProxy') return true;
if (mock && host.Object.prototype.hasOwnProperty.call(mock, key)) return mock[key];
if (key === 'constructor') return Object;
if (key === '__proto__') return Object.prototype;
if (key === '__defineGetter__') return fakeDefineGetter(receiver, true);
if (key === '__defineSetter__') return fakeDefineSetter(receiver, true);
try {
if (descriptor.get || descriptor.set) {
return host.Object.defineProperty(target, key, {
get: Decontextify.value(descriptor.get, null, deepTraps) || undefined,
set: Decontextify.value(descriptor.set, null, deepTraps) || undefined,
enumerable: descriptor.enumerable === true,
configurable: descriptor.configurable === true
});
} else {
return host.Object.defineProperty(target, key, {
value: Decontextify.value(descriptor.value, null, deepTraps),
writable: descriptor.writable === true,
enumerable: descriptor.enumerable === true,
configurable: descriptor.configurable === true
});
}
} catch (e) {
throw Contextify.value(e);
}
},
getPrototypeOf: (target) => {
return Object.prototype;
},
setPrototypeOf: (target) => {
throw new VMError(OPNA);
}
}, traps, deepTraps));
try {
return Contextify.value(object[key], null, deepTraps, flags);
} catch (e) {
throw Contextify.value(e);
}
};
base.set = (target, key, value, receiver) => {
if (flags && flags.protected && typeof value === 'function') return false;
Contextify.proxies.set(object, proxy);
Contextified.set(proxy, object);
return proxy;
},
value: (value, traps, deepTraps, flags, mock) => {
if (Decontextified.has(value)) {
// Decontextified object has returned back to vm
return Decontextified.get(value);
} else if (Contextify.proxies.has(value)) {
// Contextified proxy already exists, reuse
return Contextify.proxies.get(value);
try {
object[key] = Decontextify.value(value);
return true;
} catch (e) {
throw Contextify.value(e);
}
};
base.getOwnPropertyDescriptor = (target, prop) => {
let def;
try {
// If for some reason we get already contextified value, get out.
// Contextifying already contextified value breaks the security.
if (value instanceof local.Object) return value;
def = host.Object.getOwnPropertyDescriptor(object, prop);
} catch (e) {
throw new VMError('Failed to contextify object.');
throw Contextify.value(e);
}
switch (typeof value) {
case 'object':
try {
if (value === null) {
return null;
} else if (value instanceof host.Number) { return host.Number(value);
} else if (value instanceof host.String) { return host.String(value);
} else if (value instanceof host.Boolean) { return host.Boolean(value);
} else if (value instanceof host.Date) { return Contextify.instance(value, Date, deepTraps, flags);
} else if (value instanceof host.RangeError) { return Contextify.instance(value, RangeError, deepTraps, flags);
} else if (value instanceof host.ReferenceError) { return Contextify.instance(value, ReferenceError, deepTraps, flags);
} else if (value instanceof host.SyntaxError) { return Contextify.instance(value, SyntaxError, deepTraps, flags);
} else if (value instanceof host.TypeError) { return Contextify.instance(value, TypeError, deepTraps, flags);
} else if (value instanceof host.VMError) { return Contextify.instance(value, VMError, deepTraps, flags);
} else if (value instanceof host.Error) { return Contextify.instance(value, Error, deepTraps, flags);
} else if (value instanceof host.Array) { return Contextify.instance(value, Array, deepTraps, flags);
} else if (value instanceof host.RegExp) { return Contextify.instance(value, RegExp, deepTraps, flags);
} else if (value instanceof host.Map) { return Contextify.instance(value, Map, deepTraps, flags);
} else if (value instanceof host.WeakMap) { return Contextify.instance(value, WeakMap, deepTraps, flags);
} else if (value instanceof host.Set) { return Contextify.instance(value, Set, deepTraps, flags);
} else if (value instanceof host.WeakSet) { return Contextify.instance(value, WeakSet, deepTraps, flags);
} else if (value instanceof host.Promise) { return Contextify.instance(value, Promise, deepTraps, flags);
} else if (value instanceof host.Buffer) { return Contextify.instance(value, LocalBuffer, deepTraps, flags);
} else {
return Contextify.object(value, traps, deepTraps, flags, mock);
}
} catch (e) {
throw Contextify.value(e);
}
case 'function':
return Contextify.function(value, traps, deepTraps, flags, mock);
// Following code prevents V8 to throw
// TypeError: 'getOwnPropertyDescriptor' on proxy: trap reported non-configurability for property '<prop>'
// which is either non-existant or configurable in the proxy target
case 'undefined':
return undefined;
if (!def) {
return undefined;
} else if (def.get || def.set) {
return {
get: Contextify.value(def.get, null, deepTraps, flags) || undefined,
set: Contextify.value(def.set, null, deepTraps, flags) || undefined,
enumerable: def.enumerable === true,
configurable: def.configurable === true
};
} else {
return {
value: Contextify.value(def.value, null, deepTraps, flags),
writable: def.writable === true,
enumerable: def.enumerable === true,
configurable: def.configurable === true
};
}
};
base.defineProperty = (target, key, descriptor) => {
// There's a chance accessing a property throws an error so we must not access them
// in try catch to prevent contextyfing local objects.
const getter = Decontextify.value(descriptor.get, null, deepTraps, flags);
const setter = Decontextify.value(descriptor.set, null, deepTraps, flags);
const valuer = Decontextify.value(descriptor.value, null, deepTraps, flags);
const enumerable = descriptor.enumerable === true;
const configurable = descriptor.configurable === true;
const writable = descriptor.writable === true;
default: // string, number, boolean, symbol
return value;
if (flags && flags.protected) {
if (typeof getter === 'function' || typeof setter === 'function' || typeof valuer === 'function') return false;
}
},
globalValue: (value, name) => {
return (global[name] = Contextify.value(value));
},
readonly: (value, mock) => {
return Contextify.value(value, null, FROZEN_TRAPS, null, mock);
},
protected: (value, mock) => {
return Contextify.value(value, null, null, {protected: true}, mock);
try {
if (getter || setter) {
return host.Object.defineProperty(object, key, {
get: getter || undefined,
set: setter || undefined,
enumerable: enumerable,
configurable: configurable
});
} else {
return host.Object.defineProperty(object, key, {
value: valuer,
writable: writable,
enumerable: enumerable,
configurable: configurable
});
}
} catch (e) {
throw Contextify.value(e);
}
};
base.getPrototypeOf = (target) => {
return local.Object.prototype;
};
base.setPrototypeOf = (target) => {
throw new VMError(OPNA);
};
base.has = (target, key) => {
try {
return key in object;
} catch (e) {
throw Contextify.value(e);
}
};
base.isExtensible = target => {
try {
return Contextify.value(host.Object.isExtensible(object));
} catch (e) {
throw Contextify.value(e);
}
};
base.ownKeys = target => {
try {
return Contextify.value(host.Reflect.ownKeys(object));
} catch (e) {
throw Contextify.value(e);
}
};
base.preventExtensions = target => {
try {
host.Object.preventExtensions(object);
return true;
} catch (e) {
throw Contextify.value(e);
}
};
base.enumerate = target => {
try {
return Contextify.value(host.Reflect.enumerate(object));
} catch (e) {
throw Contextify.value(e);
}
};
const proxy = new host.Proxy(object, host.Object.assign(base, traps, deepTraps));
Contextify.proxies.set(object, proxy);
Contextified.set(proxy, object);
return proxy;
};
Contextify.value = (value, traps, deepTraps, flags, mock) => {
if (Decontextified.has(value)) {
// Decontextified object has returned back to vm
return Decontextified.get(value);
} else if (Contextify.proxies.has(value)) {
// Contextified proxy already exists, reuse
return Contextify.proxies.get(value);
}
try {
// If for some reason we get already scoped value, get out.
// Contextifying already scoped value breaks the security.
if (instanceOf(value, local.Object)) return value;
} catch (e) {
throw new VMError('Failed to contextify object.');
}
switch (typeof value) {
case 'object':
try {
if (value === null) {
return null;
} else if (instanceOf(value, host.Number)) { return host.Number(value);
} else if (instanceOf(value, host.String)) { return host.String(value);
} else if (instanceOf(value, host.Boolean)) { return host.Boolean(value);
} else if (instanceOf(value, host.Date)) { return Contextify.instance(value, Date, deepTraps, flags);
} else if (instanceOf(value, host.RangeError)) { return Contextify.instance(value, RangeError, deepTraps, flags);
} else if (instanceOf(value, host.ReferenceError)) { return Contextify.instance(value, ReferenceError, deepTraps, flags);
} else if (instanceOf(value, host.SyntaxError)) { return Contextify.instance(value, SyntaxError, deepTraps, flags);
} else if (instanceOf(value, host.TypeError)) { return Contextify.instance(value, TypeError, deepTraps, flags);
} else if (instanceOf(value, host.VMError)) { return Contextify.instance(value, VMError, deepTraps, flags);
} else if (instanceOf(value, host.Error)) { return Contextify.instance(value, Error, deepTraps, flags);
} else if (instanceOf(value, host.Array)) { return Contextify.instance(value, Array, deepTraps, flags);
} else if (instanceOf(value, host.RegExp)) { return Contextify.instance(value, RegExp, deepTraps, flags);
} else if (instanceOf(value, host.Map)) { return Contextify.instance(value, Map, deepTraps, flags);
} else if (instanceOf(value, host.WeakMap)) { return Contextify.instance(value, WeakMap, deepTraps, flags);
} else if (instanceOf(value, host.Set)) { return Contextify.instance(value, Set, deepTraps, flags);
} else if (instanceOf(value, host.WeakSet)) { return Contextify.instance(value, WeakSet, deepTraps, flags);
} else if (instanceOf(value, host.Promise)) { return Contextify.instance(value, Promise, deepTraps, flags);
} else if (instanceOf(value, host.Buffer)) { return Contextify.instance(value, LocalBuffer, deepTraps, flags);
} else if (host.Object.getPrototypeOf(value) === null) {
return Contextify.instance(value, null, deepTraps, flags);
} else {
return Contextify.object(value, traps, deepTraps, flags, mock);
}
} catch (e) {
throw Contextify.value(e);
}
case 'function':
return Contextify.function(value, traps, deepTraps, flags, mock);
case 'undefined':
return undefined;
default: // string, number, boolean, symbol
return value;
}
};
Contextify.globalValue = (value, name) => {
return (global[name] = Contextify.value(value));
};
Contextify.readonly = (value, mock) => {
return Contextify.value(value, null, FROZEN_TRAPS, null, mock);
};
Contextify.protected = (value, mock) => {
return Contextify.value(value, null, null, {protected: true}, mock);
};

@@ -534,0 +656,0 @@ const LocalBuffer = global.Buffer = Contextify.readonly(host.Buffer, {

@@ -16,3 +16,3 @@ {

],
"version": "3.6.6",
"version": "3.6.7",
"main": "index.js",

@@ -19,0 +19,0 @@ "repository": "github:patriksimek/vm2",

@@ -36,2 +36,3 @@ # vm2 [![NPM Version][npm-image]][npm-url] [![NPM Downloads][downloads-image]][downloads-url] [![Package Quality][quality-image]][quality-url] [![Travis CI][travis-image]][travis-url] [![Known Vulnerabilities][snyk-image]][snyk-url]

new VM().run('this.constructor.constructor("return process")().exit()');
// Throws ReferenceError: process is not defined
```

@@ -38,0 +39,0 @@