diff --git a/lib/setup-sandbox.js b/lib/setup-sandbox.js index 2149cc3..2c80dbc 100644 --- a/lib/setup-sandbox.js +++ b/lib/setup-sandbox.js @@ -51,7 +51,10 @@ const { AsyncGeneratorFunction } = data; -const localWeakMapGet = LocalWeakMap.prototype.get; +const { + get: localWeakMapGet, + set: localWeakMapSet +} = LocalWeakMap.prototype; function localUnexpected() { return new VMError('Should not happen'); @@ -282,8 +285,8 @@ if (typeof OriginalCallSite === 'function') { } return value(error, sst); }; - wrappedPrepareStackTrace.set(value, newWrapped); - wrappedPrepareStackTrace.set(newWrapped, newWrapped); + localReflectApply(localWeakMapSet, wrappedPrepareStackTrace, [value, newWrapped]); + localReflectApply(localWeakMapSet, wrappedPrepareStackTrace, [newWrapped, newWrapped]); currentPrepareStackTrace = newWrapped; } })) throw localUnexpected(); diff --git a/test/vm.js b/test/vm.js index 7dda4db..15eb140 100644 --- a/test/vm.js +++ b/test/vm.js @@ -1058,6 +1058,18 @@ describe('VM', () => { const sst = vm2.run('Error.prepareStackTrace = (e,sst)=>sst;const sst = new Error().stack;Error.prepareStackTrace = undefined;sst'); assert.strictEqual(vm2.run('sst=>Object.getPrototypeOf(sst)')(sst), vm2.run('Array.prototype')); assert.throws(()=>vm2.run('sst=>sst[0].getThis().constructor.constructor')(sst), /TypeError: Cannot read propert.*constructor/); + assert.throws(()=>vm2.run(` + const { set } = WeakMap.prototype; + WeakMap.prototype.set = function(v) { + return set.call(this, v, v); + }; + Error.prepareStackTrace = + Error.prepareStackTrace = + (_, c) => c.map(c => c.getThis()).find(a => a); + const { stack } = new Error(); + Error.prepareStackTrace = undefined; + stack.process + `)); }); it('Node internal prepareStackTrace attack', () => {