The problem
I'm creating a program that runs some user scripts in a confined and safe environment.
Since the users are able to share projects from one to another it could be really dangerous to do let fn = new Function(userScript);
to load a script because, as the majority of the answers to this question say, it could be used to run malicious scripts or modify the page's content by accessing global variables like document
or window
.
So I was thinking if it was possible to do something like this:
class MathHandler { ... } // Contains 'mathStuff' method
let globalVariable = "global!";
function init()
{
let localVariable = "local!"
let script = new Function('handler', '
// This script shoudn't be able to access any variables (global or local)
console.log(globalVariable); // Should give error
console.log(localVariable); // Should also error
document.getElementById("MyCanvas") // Same as before
let foo = "bar";
console.log(foo); // Should work fine
handler.mathStuff("pow", 23); // This script should also be able to access given arguments
';
func(MathHandler); //invoke the function using arguments
eval(script, MathHandler);
}
init();
I also created a simple scheme to illustrate better the situation.
TL;DR: I'm trying to execute a string as a code without making it able to access local or global variables/methods.
What I tried to do
I tried searching around the web for some answers but I couldn't find anything, probably because of some problems I had finding the correct 'terms' to describe the situation.
The closest answer to what I'm trying to achieve was a post talking about simulating a whole virtual machine that runs JavaScript, in Javascript, which I think it's a bit too much for this case. I also thought about using another language (like how Unity uses interacts with c# codes via c++) but I didn't think it was a good idea.