Giter Club home page Giter Club logo

isolated-runtime's Introduction

Isolated Runtime

npm version Build Status

isolated-runtime is a library that provides a secure, performant and dev-friendly approach for running untrusted JS code in an isolated context.

Why untrusted code?

You might be offering your users to customize your product using customg JS code that will run for certain system events, provide a complete serverless solution for their code, or allow them to create their own rules engine based on JS objects and statements - whatever that might be, all of the scenarios above involve accepting JS code from the user and executing it on your own servers. That might pose a huge security risk in case you don't enforce any limitations on that code, unless you run it within some sort a sandbox - an isolated runtime-context that will prevent it from accessing or modifying undesired resources.

Key concepts

The driving idea behind isolated-runtime is having the untrusted code as files deployed to some filesystem, then having isolated-runtime load a module from one of those files, and executing a function from that module with the provided arguments, returning a Promise that resolves to the function's return value. The function's runtime-context is isolated from the host's one, and even better - multiple instances of the same function can be run without clashing with each other via global state.

Usage examples

Assume the following file structure (with the modules folder represented code submitted from an untrusted source):

├───index.js
├───modules
│   ├─module1.js
│   ├─module2.js
// module1.js

function a() {
  global.a = 1
  return global.a 
}

// module2.js
function b() {
  return global.a
}

// index.js
const { IsolatedRuntime } = require("isolated-runtime");
const runtime = new IsolatedRuntime();

global.a = 3

const result1 = await runtime.run({
  folder: path.resolve('./modules')
  file: "module1.js",
  funcName: "a",
  args: []
});

console.log('result1: ', result1)
console.log('global.a: ', global.a)

const result2 = await runtime.run({
  folder: path.resolve('./modules')
  file: "module2.js",
  funcName: "b",
  args: []
});

console.log('result2: ', result2)
console.log('global.a: ', global.a)

The code above will print:

result1: 1
global.a: 3
result2: undefined
global.a: 3

Note that global.a was never modified by any of the invocations - since each got its own fresh, sandboxed version of global - completely detached from the global scope in index.js.

Malicious behavior

With untrusted code comes untrusted behavior - imagine such code performs a process.exit() or while (true) {} statenents - in both cases someone is trying to abort or halt the main process hosting the untrusted code runtime. To eliminate that risk, we've combined two different concepts:

  1. Context isolation - process is not availble in the untrusted code's runtime context (i.e., is not a variable that can be referenced in its closure).
  2. Host-process isolation - while (true) { } cannot be blocked beforehand, but since the untrusted code is being run inside a thread - the infinite loop will only block that thread, and will eventually result in a timeout exception aborting the execution. That way, no untrusted code can affect the host process itself.

Getting Started

Install isolated-runtime:

npm install --save isolated-runtime

In your script (that can be anything from a cli-tool up to a fully-blown Express-base Node server):

const { IsolatedRuntime } = require("isolated-runtime");

const runtime = new IsolatedRuntime(/* options */);
const result = await runtime.run({
  folder: "/path/to/folder"
  file: "relative/path/to/file",
  funcName: "functionName",
  args: [/* function arguments */]
});

Contributing to isolated-runtime

We support Node 10 and updwards, so make sure you have the latest Node 10.x version. We also use lenra for managing our monorepo, so make sure to add new modules - if necessary - using the appropriate lenra command and conventions. Once you've got your issue or suggestion approved for contribution, submit a PR:

  1. clone the repo
  2. Run npm i
  3. Run all the tests using npm t
  4. Run npm run benchmark and take note of the results.
  5. Add tests for your bug-fix or feature, apply the code changes and make sure npm t runs all the test successfully.
  6. Make sure you've changed the documentation accordingly, if applicable.
  7. Finally, run the benchmark test again, to make sure no major impact has been introduced by your changes.

isolated-runtime's People

Contributors

github-sheriff avatar harelmo avatar idan-at avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Forkers

itaykor yurynix

isolated-runtime's Issues

Bridge between isolated and non-isolated code?

Other tools similar to this (such as VM2) have the ability to communicate across the sandbox, so that code inside the sandbox can still call a handful of non-isolated methods. Can you provide an example of this?

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.