Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NodeJS VM2 proper way to access console when set to 'redirect'

I'm using the VM2 package to run user code. I'm trying to intercept console output and have set the NodeVM object's console property to 'redirect':

    // Create a new sandbox VM for this request
    const vm = new NodeVM( {
        console: 'redirect',
        timeout: 30000,
        sandbox: { request, state, response },
        require: {
            external: true
        }
    });

According to the documentation that redirects console output to 'events'. I'm new to NodeJS, how do I hook into those events to capture the console.log messages executed inside the Sandbox?

like image 463
Gregory Billings Avatar asked May 11 '18 19:05

Gregory Billings


1 Answers

After digging through the source code, I found this file where the event emit is occuring:

sandbox.js

if (vm.options.console === 'inherit') {
    global.console = Contextify.readonly(host.console);
} else if (vm.options.console === 'redirect') {
    global.console = {
        log(...args) {
            vm.emit('console.log', ...Decontextify.arguments(args));
            return null;
        },
        info(...args) {
            vm.emit('console.info', ...Decontextify.arguments(args));
            return null;
        },
        warn(...args) {
            vm.emit('console.warn', ...Decontextify.arguments(args));
            return null;
        },
        error(...args) {
            vm.emit('console.error', ...Decontextify.arguments(args));
            return null;
        },
        dir(...args) {
            vm.emit('console.dir', ...Decontextify.arguments(args));
            return null;
        },
        time: () => {},
        timeEnd: () => {},
        trace(...args) {
            vm.emit('console.trace', ...Decontextify.arguments(args));
            return null;
        }
    };
}

All you need to do to listen to these events is to bind an event listener on the vm you've created:

// Create a new sandbox VM for this request
    const vm = new NodeVM( {
        console: 'redirect',
        require: {
            external: ['request']
        }
    });

    vm.on('console.log', (data) => {
        console.log(`VM stdout: ${data}`);
      });

Likewise, you can bind to console.log, console.info, console.warn, console.error, console.dir, and console.trace. Hopefully this will save someone else some time.

like image 167
Gregory Billings Avatar answered Oct 18 '22 10:10

Gregory Billings