GithubHelp home page GithubHelp logo

nhaehnle / sandcastle Goto Github PK

View Code? Open in Web Editor NEW

This project forked from bcoe/sandcastle

0.0 3.0 0.0 136 KB

An attempted sandbox that cannot safely run untrusted JavaScript

License: MIT License

JavaScript 100.00%

sandcastle's Introduction

SandCastle

A broken sandbox which cannot safely run untrusted JavaScript.

The Impetus

For a project I'm working on, I needed the ability to run untrusted JavaScript code.

I had a couple specific requirements:

  • I wanted the ability to whitelist an API for inclusion within the sandbox.
  • I wanted to be able to run multiple untrusted scripts in the same sandboxed subprocess.
  • I wanted good error reporting and stack-traces, when a sandboxed script failed.

I could not find a library that met all these requirements, enter SandCastle.

What Makes SandCastle Different?

  • It allows you to queue up multiple scripts for execution within a single sandbox.
    • This better suits Node's evented architecture.
  • It provides reasonable stack traces when the execution of a sandboxed script fails.
  • It allows an API to be provided to the sandboxed script being executed.
  • It provides all this in a simple, well-tested, API.

Installation

npm install sandcastle

Creating and Executing a Script

var SandCastle = require('sandcastle').SandCastle;

var sandcastle = new SandCastle();

var script = sandcastle.createScript("\
  exports.main = function() {\
    exit('Hey ' + name + ' Hello World!');\
  }\
");

script.on('exit', function(err, output) {
    console.log(output); // Hello World!
});

script.run({name: 'Ben'});// we can pass variables into run.

Outputs

Hey Ben Hello World!
  • exit(output): from within untrusted code, causes a sandboxed script to return.
    • Any JSON serializable data passed into exit() will be passed to the output parameter of an exit event.
  • on('exit'): this event is called when an untrusted script finishes execution.
  • run() starts the execution of an untrusted script.

Executing Scripts on Pool of SandCastles

A pool consists of several SandCastle child-processes, which will handle the script execution. Pool-object is a drop-in replacement of single Sandcastle instance. Only difference is, when creating the Pool-instance.

You can specify the amount of child-processes with parameter named numberOfInstances (default = 1).

var Pool = require('sandcastle').Pool;

var poolOfSandcastles = new Pool( { numberOfInstances: 3 } );

var script = poolOfSandcastles.createScript("\
  exports.main = function() {\
    exit('Hello World!');\
  }\
");

script.on('exit', function(err, output) {
    console.log(output);
});

script.run();

Handling Timeouts

If a script takes too long to execute, a timeout event will be fired:

var SandCastle = require('sandcastle').SandCastle;

var sandcastle = new SandCastle();

var script = sandcastle.createScript("\
  exports.main = function() {\
    while(true) {};\
  }\
");

script.on('exit', function(err, output) {
    console.log('this will never happen.');
});

script.on('timeout', function() {
    console.log('I timed out, oh what a silly script I am!');
});

script.run();

Outputs

I timed out, oh what a silly script I am!

Handling Errors

If an exception occurs while executing a script, it will be returned as the first parameter in an on(exit) event.

var SandCastle = require('sandcastle').SandCastle;

var sandcastle = new SandCastle();

var script = sandcastle.createScript("\
  exports.main = function() {\n\
    require('fs');\n\
  }\
");

script.on('exit', function(err, output) {
    console.log(err.message);
    console.log(err.stack);
});

script.run();

Outputs

require is not defined
ReferenceError: require is not defined
    at Object.main ([object Context]:2:5)
    at [object Context]:4:9
    at Sandbox.executeScript (/Users/bcoe/hacking/open-source/sandcastle/lib/sandbox.js:58:8)
    at Socket.<anonymous> (/Users/bcoe/hacking/open-source/sandcastle/lib/sandbox.js:16:13)
    at Socket.emit (events.js:64:17)
    at Socket._onReadable (net.js:678:14)
    at IOWatcher.onReadable [as callback] (net.js:177:10)

Providing an API

When creating an instance of SandCastle, you can provide an API. Functions within this API will be available inside of the untrustred scripts being executed.

AN Example of an API:

var fs = require('fs');

exports.api = {
  getFact: function(callback) {
    fs.readFile('./examples/example.txt', function (err, data) {
      if (err) throw err;
      callback(data.toString());
    });
  },
  setTimeout: function(callback, timeout) {
    setTimeout(callback, timeout);
  }
}

A Script Using the API:

var SandCastle = require('sandcastle').SandCastle;

var sandcastle = new SandCastle({
  api: './examples/api.js'
});

var script = sandcastle.createScript("\
  exports.main = function() {\
    getFact(function(fact) {\
      exit(fact);\
    });\
  }\
");

script.on('exit', function(err, result) {
  equal(result, 'The rain in spain falls mostly on the plain.', prefix);
  sandcastle.kill();
  finished();
});

script.run();

SandCastle will be an ongoing project, please be liberal with your feedback, criticism, and contributions.

Copyright

Copyright (c) 2012 Benjamin Coe. See LICENSE.txt for further details.

sandcastle's People

Contributors

bcoe avatar blalor avatar gavinjoyce avatar ndob avatar nhaehnle avatar rkrzr avatar

Watchers

 avatar  avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.