patriksimek/vm2

__proto__ property of a Proxy wrapping an object not containing __proto__ property behaves differently from expected that.

kagesakura opened this issue · 2 comments

For instance, it is expected to return undefined, but null is returned.

const { VM } = require('vm2');

console.log(new VM().run('({ __proto__: null })').__proto__);
// output(VM): null

console.log({ __proto__: null }.__proto__);
// output(normal): undefined

This is expected. In case the object does not have a __proto__ property VM emulates it even if there is a __proto__ property in the prototype chain or, as in your case there is none. The value of the __proto__ property in the chain does also not matter.

const { VM } = require('vm2');

console.log(new VM().run('({ __proto__: { __proto__: null, ["__proto__"]: 1 } })').__proto__);
// output(VM): [Object: null prototype] {}

console.log({ __proto__: { __proto__: null, ["__proto__"]: 1 } }.__proto__);
// output(normal): 1

This is done for a reason and will not be changed.

Since scripts should not get access to prototypes. If they could it would be trivial to get the Function constructor and escape. Therefore __proto__ is handled specially and a sandboxed prototype is returned instead.