How to get the result of the code which is run by Node vm2

3.2k Views Asked by At

Recently, i have been trying to implement sandbox execution using the package vm2 which has be published by @Patrik Šimek

I am trying to run some js code, which i am considering it to be a custom Logic, i am storing this logic in a string variable.

I need to execute this custom logic in a sandbox environment (since this is the untrusty code) and get back the response in the actual environment to continue with the normal application flow based on this result.

I tried several methods to get the end result. The custom logic is being executed successfully inside the sandbox but i am not able to find a way to send this result back to the main process, but instead i am getting the result as undefined. Therefore, nothing has worked so far.

Hope i get some answers here.

Custom Logic (which will be stored inside a string)

function addValues(a,b){
   var c = a + b;
   console.log('Addition of 2 values');
   console.log(c); 
   return c;
}

addValues(10,10); // function call

Actual Implementation

// vm2 
 const {NodeVM} = require('vm2');
        const vm = new NodeVM({
            console: 'inherit',
            sandbox: {},
            require: {
                external: true,
                builtin: ['fs','path'],
                root: "./",
                mock: {
                    fs: {
                        readFileSync() { return 'Nice try!';}
                    }
                },
                wrapper : ""
            }
        });


// Sandbox function
let functionInSandbox = vm.run("module.exports = function(customLogic){
                                    customLogic //need to execute this custom logic 
                               });



// Make a call to execute untrusty code by passing it as an argument
// to sandbox environment and obtain the result 

var resultOfSandbox =  functionInSandbox(customLogic);
console.log("Result of Sandbox  :");
console.log(resultOfSandbox); // undefined (need to get the result of custom logic execution)
2

There are 2 best solutions below

2
On

You need to define a sandbox variable. Declare an empty object, append it to your sandbox option and inside your script add another property to your object. I guess a code snippet would speak for itself:

const c = `
function addValues(a,b){
  var c = a + b;
  console.log('Addition of 2 values');
  console.log(c); 
  return c;
}

// we'll define ext as a sandbox variable, so it will be available
ext.exports = addValues(10,10); // function call
`;

let ext = {};
const { NodeVM } = require( 'vm2' );
const vm = new NodeVM( {
  console: 'inherit',
  // pass our declared ext variable to the sandbox
  sandbox: { ext },
  require: {
    external: true,
    builtin: ['fs', 'path'],
    root: './',
  },
} );

// run your code and see the results in ext
vm.run( c, 'vm.js' );
console.log( ext );
0
On

This code works:

let result = {};
code='output.testOut=1;';
const vm = new VM({
            timeout: 1000,
            allowAsync: false,
            sandbox: { ...data, output: result },
});
const script = new VMScript(code);
const r = vm.run(script);
console.log(result);