Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Running Untrusted Code in Node

Dave Wasmer
February 25, 2014

Running Untrusted Code in Node

Running untrusted code in Node in a safe mode while handling the lode.

Dave Wasmer

February 25, 2014
Tweet

More Decks by Dave Wasmer

Other Decks in Technology

Transcript

  1. Lots o’ stuff • Data storage • User management •

    Twitter, Facebook, G+, LinkedIn • OAuth, LDAP, Active Directory • File storage • don’t forget CDN delivery • Push notifications • Emails • 3rd Party API Integration • Analytics • a whole lot more ..
  2. The Problem We needed a safe, scalable way to run

    arbitrary (possibly malicious) JavaScript on our servers.
  3. Safety • Can’t allow access to: • filesystem • shared

    memory • Kinvey internals • State is evil!
  4. Scalablity • Needs to scale horizontally • i.e. spin up

    new instances on-demand • automatically add to resource pool • Optimize for usage • not running huge computations - short, frequent bursts of activity • 2x per API request is possible!
  5. Our solution to scalability KCS KCS KCS KBL KBL KBL

    Redis Work Master Child Child Child Child
  6. Our solution to scalability KCS KCS KCS KBL KBL KBL

    Redis Work Master Child Child Child Child
  7. Our solution to scalability KCS KCS KCS KBL KBL KBL

    Redis Work Master Child Child Child Child
  8. Our solution to scalability KCS KCS KCS KBL KBL KBL

    Redis Work Master Child Child Child Child
  9. Safety Concerns • How to run arbitrary JS code? •

    Three issues • System access (filesystem, network, etc) • Application access (application state, data, etc) • Stupidity / DoS (while (true), forgot to signal async completed)
  10. Our solution to system access ! // Setting things up

    ! try { script = vm.createScript(codeAsStr); } catch (e) { // syntax error! } ! sandbox = generateNewSandbox()
  11. generateNewSandbox = function(){ ! var sandbox = {}; sandbox.complete =

    function(){ runNextTask(); }; sandbox.whateverYouWant = function(){ ... } return sandbox; ! } Our solution to system access
  12. ! // Running the untrusted script try { script.runInNewContext(sandbox) }

    catch (e) { // e will be any immediate (synchronous) // runtime errors } Our solution to system access
  13. Our solution to application access ! // inside generateNewSandbox() !

    sandbox.db = { find: function(query, callback) { // do db stuff callback(null, result) // <- Careful! }, ...
 }
  14. Stupidity / DoS • while (true) {} // single-threaded ftw!

    • function onPreSave(req, res, modules) {
 doSomeAsyncStuff()
 } // kthxbai • function doSomeAsyncStuff() {
 setTimeout(function(){ 
 throw new Error() 
 }, 100000); // muhahaha
 }
  15. Our solution to stupidity / DoS ! // For handling

    callback errors process.on(‘uncaughtException’, function(){ // handle it here });