Comparing version 3.4.3 to 3.4.4
@@ -19,2 +19,10 @@ 'use strict' | ||
const ERROR_CST = 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 | ||
} | ||
@@ -329,2 +337,4 @@ // Map of contextified objects to original objects | ||
set: (target, key, value, receiver) => { | ||
if (object.isVMProtected && typeof value === 'function') throw new VMError('Assigning a function to protected object is prohibited.'); | ||
try { | ||
@@ -366,2 +376,4 @@ object[key] = Decontextify.value(value); | ||
defineProperty: (target, key, descriptor) => { | ||
if (object.isVMProtected && typeof descriptor.value === 'function') throw new VMError('Assigning a function to protected object is prohibited.'); | ||
try { | ||
@@ -431,5 +443,7 @@ if (descriptor.get || descriptor.set) { | ||
} else { | ||
if (value.isVMFrozen) deepTraps = Object.assign({}, deepTraps, FROZEN_TRAPS); | ||
return Contextify.object(value, traps, deepTraps, mock); | ||
} | ||
case 'function': | ||
if (value.isVMFrozen) deepTraps = Object.assign({}, deepTraps, FROZEN_TRAPS); | ||
return Contextify.function(value, traps, deepTraps, mock); | ||
@@ -448,10 +462,3 @@ | ||
readonly: function(value, mock) { | ||
return Contextify.value(value, null, { | ||
set: (target, key) => false, | ||
setPrototypeOf: (target, key) => false, | ||
defineProperty: (target, key) => false, | ||
deleteProperty: (target, key) => false, | ||
isExtensible: (target, key) => false, | ||
preventExtensions: (target) => false | ||
}, mock); | ||
return Contextify.value(value, null, FROZEN_TRAPS, mock); | ||
} | ||
@@ -458,0 +465,0 @@ } |
@@ -36,13 +36,7 @@ const fs = require('fs'); | ||
return new Proxy(object, { | ||
get: (target, key) => { | ||
if (PROTECTED.includes(key)) return Reflect.get(target, key); | ||
return _freeze(Reflect.get(target, key)); | ||
}, | ||
set: (target, key) => { throw new VMError('Object is read-only.') }, | ||
setPrototypeOf: (target, key) => { throw new VMError('Object is read-only.') }, | ||
defineProperty: (target, key) => { throw new VMError('Object is read-only.') }, | ||
deleteProperty: (target, key) => { throw new VMError('Object is read-only.') }, | ||
isExtensible: (target, key) => false, | ||
preventExtensions: (target) => { throw new VMError('Object is read-only.') } | ||
Object.defineProperty(object, 'isVMFrozen', { | ||
enumerable: false, | ||
configurable: false, | ||
writable: false, | ||
value: true | ||
}); | ||
@@ -58,16 +52,7 @@ } | ||
return new Proxy(object, { | ||
get: (target, key) => { | ||
if (PROTECTED.includes(key)) return Reflect.get(target, key); | ||
return _protect(Reflect.get(target, key)); | ||
}, | ||
set: (target, key, value) => { | ||
if (PROTECTED.includes(key)) throw new VMError(`Changing ${key} on protected object is prohibited.`); | ||
if (typeof value === 'function') throw new VMError('Assigning a function to protected object is prohibited.'); | ||
return Reflect.set(target, key, value); | ||
}, | ||
setPrototypeOf: (target, key) => { throw new VMError('Changing prototype on protected object is prohibited.') }, | ||
defineProperty: (target, key) => { throw new VMError('Defining property on protected object is prohibited.') }, | ||
deleteProperty: (target, key) => Reflect.deleteProperty(target, key), | ||
preventExtensions: (target) => { throw new VMError('Method is prohibited on protected object.') } | ||
Object.defineProperty(object, 'isVMProtected', { | ||
enumerable: false, | ||
configurable: false, | ||
writable: false, | ||
value: true | ||
}); | ||
@@ -74,0 +59,0 @@ } |
@@ -16,3 +16,3 @@ { | ||
], | ||
"version": "3.4.3", | ||
"version": "3.4.4", | ||
"main": "index.js", | ||
@@ -19,0 +19,0 @@ "repository": { |
@@ -78,3 +78,4 @@ # 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] | ||
* [Error handling](#error-handling) | ||
* [Read-only objects](#read-only-objects) | ||
* [Read-only objects](#read-only-objects-experimental) | ||
* [Protected objects](#protected-objects-experimental) | ||
* [Cross-sandbox relationships](#cross-sandbox-relationships) | ||
@@ -235,5 +236,5 @@ * [CLI](#cli) | ||
## Read-only objects | ||
## Read-only objects (experimental) | ||
To prevent sandboxed script to add/change/delete properties to/from the proxied objects, you can use `VM.freeze`/`NodeVM.freeze` methods to make the object read-only. Rather than freezing the object itself (like builtin `Object.freeze` method does) it creates a new proxy so the original object remains untouched. | ||
To prevent sandboxed script to add/change/delete properties to/from the proxied objects, you can use `VM.freeze`/`NodeVM.freeze` methods to make the object read-only. This is only effective inside VM. Frozen objects are affected deeply. | ||
@@ -258,4 +259,6 @@ **Example without using `VM.freeze`:** | ||
```javascript | ||
VM.freeze(util); | ||
const vm = new VM({ | ||
sandbox: {util: VM.freeze(util)} | ||
sandbox: {util} | ||
}); | ||
@@ -266,2 +269,6 @@ | ||
## Protected objects (experimental) | ||
Unlike `freeze`, this method allows sandboxed script to add/modify/delete properties on object with one exception - it is not possible to attach functions. Sandboxed script is therefore not able to modify methods like `toJSON`, `toString` or `inspect`. | ||
## Cross-sandbox relationships | ||
@@ -268,0 +275,0 @@ |
@@ -683,12 +683,21 @@ const assert = require("assert"); | ||
assert.throws(() => { | ||
vm.run('x.a = () => { return `-` };'); | ||
}, /Object is read-only\./); | ||
vm.run('"use strict"; x.a = () => { return `-` };'); | ||
}, /'set' on proxy: trap returned falsish for property 'a'/); | ||
assert.throws(() => { | ||
vm.run('(y) => { y.b = () => { return `--` } }')(x); | ||
}, /Object is read-only\./); | ||
vm.run('"use strict"; (y) => { y.b = () => { return `--` } }')(x); | ||
}, /'set' on proxy: trap returned falsish for property 'b'/); | ||
assert.throws(() => { | ||
vm.run('x.c.d = () => { return `---` };'); | ||
}, /Object is read-only\./); | ||
vm.run('"use strict"; x.c.d = () => { return `---` };'); | ||
}, /'set' on proxy: trap returned falsish for property 'd'/); | ||
vm.run('x.a = () => { return `-` };'); | ||
assert.strictEqual(x.a(), 'a'); | ||
vm.run('(y) => { y.b = () => { return `--` } }')(x); | ||
assert.strictEqual(x.b(), 'b'); | ||
vm.run('x.c.d = () => { return `---` };'); | ||
assert.strictEqual(x.c.d(), 'd'); | ||
}) | ||
@@ -704,12 +713,18 @@ | ||
it('with protect', () => { | ||
let vm = new VM(), obj = {}; | ||
let vm = new VM(), obj = { | ||
date: new Date(), | ||
array: [{},{}] | ||
}; | ||
vm.run('(i) => { i.text = "test" }')(obj); | ||
VM.protect(obj); | ||
assert.throws(() => { | ||
vm.run('(i) => { i.func = () => {} }')(VM.protect(obj)); | ||
vm.run('(i) => { i.func = () => {} }')(obj); | ||
}, /Assigning a function to protected object is prohibited\./); | ||
vm.run('(i) => { delete i.func }')(VM.protect(obj)); | ||
assert.strictEqual(vm.run('(i) => i.array.map(item => 1).join(",")')(obj), '1,1'); | ||
assert.strictEqual(vm.run('(i) => /x/.test(i.date)')(obj), false); | ||
}) | ||
}) |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
73697
1826
346