I'm working on a webapp that lets you build tools in the browser to be used by others.
So, for example, someone might make a calculator app with custom buttons that take user input, process it in a certain way (currently using eval()
) and display the output. They type their script into an input and we store it. When the button is pressed, we call eval on the script, and then display the result. Not only this, but we want to let them manipulate the dom, adding elements to the screen etc - just as though we let them upload a javascript file and run it. We don't vouch for the apps' safety, just like Squarespace doesn't vouch for their users websites' safety.
In other words, we actually want to let users execute code in the browser arbitrarily, similarly to how Squarespace lets people who build websites execute arbitrary javascript to customize their website.
This can't be moved to a sandboxed server because it needs to happen in many places in real-time (some buttons trigger multiple scripts in sequence with our native functionality in between them) and interact with the DOM.
It appears we can use the Function constructor to prevent access to local variables, but clearly it's not much different from eval: eval vs function constructor
Perhaps an alternative to directly executing their functions using eval is to generate a javascript file with each script defined as a function and then to import it and call those functions? But is that any better?
We effectively want to let them create a custom javascript file and call the functions on button press (this is what Squarespace allows basically), we're just using eval because it's simpler right now.
If there's some scoping/spoofing risk with evaluating a javascript string vs importing it as a file then that's obviously worth changing to a file, but we want to let "developers" write scripts and we want to run the scripts on their behalf just like Squarespace does.
Is what we're currently doing as secure as what platforms like Squarespace are (letting you write code to a .js file and importing it on the user-created website)? Or should we be generating a javascript file with the code in it and importing it/using some other method?