Safely sandbox and execute user submitted JavaScript?

后端 未结 5 1596
别跟我提以往
别跟我提以往 2020-11-30 00:52

I would like to have the ability to let users submit arbitrary JavaScript code, which is then sent to a Node.JS server and safely executed before the output is sent back to

相关标签:
5条回答
  • 2020-11-30 00:53

    Depending on your usage, I'd suggest you also consider protecting your sandbox with a virtual environment like gVisor. You can find some info here.

    0 讨论(0)
  • 2020-11-30 01:03

    Under Node.js you may create a sandboxed child process, but you also need to append the code with "use strict";, otherwise it is possible to break the sandbox with arguments.callee.caller.

    Not sure why you need to send it to the server, because the code may also be executed in a sandboxed web-worker.

    Also take a look at my Jailed library which simplifies everything just mentioned for both Node.js and web-browser, and additionally provides an opportunity to export a set of functions into the sandbox.

    0 讨论(0)
  • 2020-11-30 01:08

    This answer is outdated as gf3 does not provide protection against sandbox breaking

    http://gf3.github.io/sandbox/ - it uses require('child_process') instead of require('vm').

    0 讨论(0)
  • 2020-11-30 01:10

    One alternative would be to use http://github.com/patriksimek/vm2:

    $ npm install vm2
    

    then:

    const {VM} = require('vm2');
    const vm = new VM();
    
    vm.run(`1 + 1`);  // => 2
    

    as mentioned in comments of other answers.

    I don't know how secure it is, but it at least claims that it runs untrusted code securely (in its README). And I couldn't find any obvious security issues so far as solutions suggested in other answers here.

    0 讨论(0)
  • 2020-11-30 01:17

    You can use sandbox support in nodejs with vm.runInContext('js code', context), sample in api documentation:

    https://nodejs.org/api/vm.html#vm_vm_runinthiscontext_code_options

    const util = require('util');
    const vm = require('vm');
    
    const sandbox = { globalVar: 1 };
    vm.createContext(sandbox);
    
    for (var i = 0; i < 10; ++i) {
        vm.runInContext('globalVar *= 2;', sandbox);
    }
    console.log(util.inspect(sandbox));
    
    // { globalVar: 1024 }
    

    WARN: As pointed by "s4y" it seems to be flawled. Please look at the comments.

    0 讨论(0)
提交回复
热议问题