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 ?