Aurieh Aurieh - 1 month ago 14
Node.js Question

node.js vm and external methods

I have a few problems working on an app that uses

vm
:

External methods calls inside an infinite
while (true) {}
loop are not timed out:

var context = {
externalMethod: function(str) {console.log(str)}
};
vm.runInNewContext("while (true) {externalMethod('test')}", context, {}, 100);


Code above runs infinitely, even after 100ms timeout is finished;

vm.runInNewContext("for (;;) {}", {}, {}, 100)


Also this.. Even without running external methods, it isn't timed out.

And one last question: how safe is it to have external method calls inside
vm2
that will run untrusted code:

var context = {
method: (str) => {
createMessage("id", str) // some external (non-sandbox) method that sends an authenticated POST request to a chat app...
}
}


So, is it possible to retrieve external
global
or
this
, using that method?

Answer

Code above runs infinitely, even after 100ms timeout is finished

timeout should be a property of the options object, not a separate argument:

vm.runInNewContext("while (true) {externalMethod('test')}", context, { timeout : 100 })

And one last question: how safe is it to have external method calls inside vm2 that will run untrusted code.

I assume you mean vm (the built-in Node module) and not vm2 here. In that case, when you call code outside of the VM, it can potentially access the globals, locals and this of the "outside" code:

const vm    = require('vm');
let SECRET  = 'this is a secret';
let context = {
  console, // to allow `console.log()` calls inside the sandboxed code
  externalMethod() {
    console.log('Secret outside:', SECRET)
  }
};
vm.runInNewContext(`
console.log('Secret inside: ', typeof SECRET);
externalMethod();
`, context);

You can't access SECRET directly from the 'inside' code, but the external method can access it. So if externalMethod has the potential of running untrusted code, it'll be unsafe.

Comments