Run unsafe code in a sandbox

One Paragraph Explainer

As a rule of thumb, one should run his own JavaScript files only. Theories aside, real-world scenarios demand to execute JavaScript files that are being passed dynamically at run-time. For example, consider a dynamic framework like webpack that accepts custom loaders and execute those dynamically during build time. In the existence of some malicious plugin we wish to minimize the damage and maybe even let the flow terminate successfully - this requires to run the plugins in a sandbox environment that is fully isolated in terms of resources, crashes and the information we share with it. Three main options can help in achieving this isolation:

  • a dedicated child process - this provides a quick information isolation but demand to tame the child process, limit its execution time and recover from errors
  • a cloud serverless framework ticks all the sandbox requirements but deployment and invoking a FaaS function dynamically is not a walk in the park
  • some npm libraries, like sandbox and vm2 allow execution of isolated code in 1 single line of code. Though this latter option wins in simplicity it provides a limited protection

Code example - Using Sandbox library to run code in isolation

  1. const Sandbox = require('sandbox');
  2. const s = new Sandbox();
  3. s.run('lol)hai', (output) => {
  4. console.log(output);
  5. //output='Syntax error'
  6. });
  7. // Example 4 - Restricted code
  8. s.run('process.platform', (output) => {
  9. console.log(output);
  10. //output=Null
  11. });
  12. // Example 5 - Infinite loop
  13. s.run('while (true) {}', (output) => {
  14. console.log(output);
  15. //output='Timeout'
  16. });