I have this turn-based NodeJs gaming app in which developers (anyone) can submit a player-robot. My NodeJS app will load all players and let them play against each other. Because I don't know anything about the code submitted I need to run it inside a sandbox.
For example, the following untrusted code might look like this:
let history = []; export default class Player { constructor () { this.history = []; } move (info) { this.history.push(info); } done(result) { history.push({result: result, history: this.history}); } } Now, in my main app I would like to do something like
import Player1 from 'sandbox/player1'; import Player2 from 'sandbox/player2'; .... for (let outer = 0; outer < 10; outer ++) { let player1 = creeateSandboxedInstance(Player1); let player2 = creeateSandboxedInstance(Player2); for(let inner = 0; inner < 1000000; inner ++) { ... let move1 = player1.move(); let move2 = player2.doMove(); ... } } What I would like the sandbox/creeateSandboxedInstance environment to take care of is:
- Player class should not give access to the filesystem / internet
- Player class should not have access to app global variables
- Any state should be reseted (like class variables)
- probably more things :)
I think that I should use the vm module. Something like this probably:
var vm = require('vm'); var script = new vm.Script('function move(info){ ... } ...', {conext}); var sandbox = script.runInNewContext(); script.move(..); // or sandbox.move(..); However, I cannot get it to work such that I can call the move method. Is something like even possible ?