Coder Social home page Coder Social logo

vm2's Introduction

vm2 NPM Version NPM Downloads Package Quality Node.js CI Known Vulnerabilities

‼️ Project Discontinued ‼️

TL;DR The library contains critical security issues and should not be used for production! The maintenance of the project has been discontinued. Consider migrating your code to isolated-vm.

Dear community,

It's been a truly remarkable journey for me since the vm2 project started nine years ago. The original intent was to devise a method for running untrusted code in Node, with a keen focus on maintaining in-process performance. Proxies, an emerging feature in JavaScript at that time, became our tool of choice for this task.

From the get-go, we recognized the arduous task that lay ahead, as we tried to safeguard against the myriad of escape scenarios JavaScript presented. However, the thrill of the chase kept us going, hopeful that we could overcome these hurdles.

Through the years, this project has seen numerous contributions from passionate individuals. I wish to extend my deepest gratitude to all of you. Special thanks go to @XmiliaH, whose unwavering dedication in maintaining and improving this library over the last 4 years was instrumental to its sustained relevance.

Unfortunately, the growing complexity of Node has brought us to a crossroads. We now find ourselves facing an escape so complicated that fixing it seems impossible. And this isn't about one isolated issue. Recent reports have highlighted that sustaining this project in its current form is not viable in the long term.

Therefore, we must announce the discontinuation of this project.

You may wonder, "What now?"

While this may seem like an end, I see it as an opportunity for you to transition your projects and adapt to a new solution. We would recommend migrating your code to the isolated-vm, a library which employs a slightly different, yet equally effective, approach to sandboxing untrusted code.

Thank you all for your support and understanding during this journey.

Warm Regards, Patrik Simek


The original Readme is available here.

vm2 is a sandbox that can run untrusted code with whitelisted Node's built-in modules. Securely!

Features

  • Runs untrusted code securely in a single process with your code side by side
  • Full control over the sandbox's console output
  • The sandbox has limited access to the process's methods
  • It is possible to require modules (built-in and external) from the sandbox
  • You can limit access to certain (or all) built-in modules
  • You can securely call methods and exchange data and callbacks between sandboxes
  • Is immune to all known methods of attacks
  • Transpiler support

How does it work

  • It uses the internal VM module to create a secure context.
  • It uses Proxies to prevent escaping from the sandbox.
  • It overrides the built-in require to control access to modules.

What is the difference between Node's vm and vm2?

Try it yourself:

const vm = require('vm');
vm.runInNewContext('this.constructor.constructor("return process")().exit()');
console.log('Never gets executed.');
const {VM} = require('vm2');
new VM().run('this.constructor.constructor("return process")().exit()');
// Throws ReferenceError: process is not defined

Installation

IMPORTANT: VM2 requires Node.js 6 or newer.

npm install vm2

Quick Example

const {VM} = require('vm2');
const vm = new VM();

vm.run(`process.exit()`); // TypeError: process.exit is not a function
const {NodeVM} = require('vm2');
const vm = new NodeVM({
    require: {
        external: true,
        root: './'
    }
});

vm.run(`
    var request = require('request');
    request('http://www.google.com', function (error, response, body) {
        console.error(error);
        if (!error && response.statusCode == 200) {
            console.log(body); // Show the HTML for the Google homepage.
        }
    });
`, 'vm.js');

Documentation

VM

VM is a simple sandbox to synchronously run untrusted code without the require feature. Only JavaScript built-in objects and Node's Buffer are available. Scheduling functions (setInterval, setTimeout and setImmediate) are not available by default.

Options:

  • timeout - Script timeout in milliseconds. WARNING: You might want to use this option together with allowAsync=false. Further, operating on returned objects from the sandbox can run arbitrary code and circumvent the timeout. One should test if the returned object is a primitive with typeof and fully discard it (doing logging or creating error messages with such an object might also run arbitrary code again) in the other case.
  • sandbox - VM's global object.
  • compiler - javascript (default) or coffeescript or custom compiler function. The library expects you to have coffee-script pre-installed if the compiler is set to coffeescript.
  • eval - If set to false any calls to eval or function constructors (Function, GeneratorFunction, etc.) will throw an EvalError (default: true).
  • wasm - If set to false any attempt to compile a WebAssembly module will throw a WebAssembly.CompileError (default: true).
  • allowAsync - If set to false any attempt to run code using async will throw a VMError (default: true).

IMPORTANT: Timeout is only effective on synchronous code that you run through run. Timeout does NOT work on any method returned by VM. There are some situations when timeout doesn't work - see #244.

const {VM} = require('vm2');

const vm = new VM({
    timeout: 1000,
    allowAsync: false,
    sandbox: {}
});

vm.run('process.exit()'); // throws ReferenceError: process is not defined

You can also retrieve values from VM.

let number = vm.run('1337'); // returns 1337

TIP: See tests for more usage examples.

NodeVM

Unlike VM, NodeVM allows you to require modules in the same way that you would in the regular Node's context.

Options:

  • console - inherit to enable console, redirect to redirect to events, off to disable console (default: inherit).
  • sandbox - VM's global object.
  • compiler - javascript (default) or coffeescript or custom compiler function (which receives the code, and it's file path). The library expects you to have coffee-script pre-installed if the compiler is set to coffeescript.
  • eval - If set to false any calls to eval or function constructors (Function, GeneratorFunction, etc.) will throw an EvalError (default: true).
  • wasm - If set to false any attempt to compile a WebAssembly module will throw a WebAssembly.CompileError (default: true).
  • sourceExtensions - Array of file extensions to treat as source code (default: ['js']).
  • require - true, an object or a Resolver to enable require method (default: false).
  • require.external - Values can be true, an array of allowed external modules, or an object (default: false). All paths matching /node_modules/${any_allowed_external_module}/(?!/node_modules/) are allowed to be required.
  • require.external.modules - Array of allowed external modules. Also supports wildcards, so specifying ['@scope/*-ver-??], for instance, will allow using all modules having a name of the form @scope/something-ver-aa, @scope/other-ver-11, etc. The * wildcard does not match path separators.
  • require.external.transitive - Boolean which indicates if transitive dependencies of external modules are allowed (default: false). WARNING: When a module is required transitively, any module is then able to require it normally, even if this was not possible before it was loaded.
  • require.builtin - Array of allowed built-in modules, accepts ["*"] for all (default: none). WARNING: "*" can be dangerous as new built-ins can be added.
  • require.root - Restricted path(s) where local modules can be required (default: every path).
  • require.mock - Collection of mock modules (both external or built-in).
  • require.context - host (default) to require modules in the host and proxy them into the sandbox. sandbox to load, compile, and require modules in the sandbox. callback(moduleFilename, ext) to dynamically choose a context per module. The default will be sandbox is nothing is specified. Except for events, built-in modules are always required in the host and proxied into the sandbox.
  • require.import - An array of modules to be loaded into NodeVM on start.
  • require.resolve - An additional lookup function in case a module wasn't found in one of the traditional node lookup paths.
  • require.customRequire - Use instead of the require function to load modules from the host.
  • require.strict - false to not force strict mode on modules loaded by require (default: true).
  • require.fs - Custom file system implementation.
  • nesting - WARNING: Allowing this is a security risk as scripts can create a NodeVM which can require any host module. true to enable VMs nesting (default: false).
  • wrapper - commonjs (default) to wrap script into CommonJS wrapper, none to retrieve value returned by the script.
  • argv - Array to be passed to process.argv.
  • env - Object to be passed to process.env.
  • strict - true to loaded modules in strict mode (default: false).

IMPORTANT: Timeout is not effective for NodeVM so it is not immune to while (true) {} or similar evil.

REMEMBER: The more modules you allow, the more fragile your sandbox becomes.

const {NodeVM} = require('vm2');

const vm = new NodeVM({
    console: 'inherit',
    sandbox: {},
    require: {
        external: true,
        builtin: ['fs', 'path'],
        root: './',
        mock: {
            fs: {
                readFileSync: () => 'Nice try!'
            }
        }
    }
});

// Sync

let functionInSandbox = vm.run('module.exports = function(who) { console.log("hello "+ who); }');
functionInSandbox('world');

// Async

let functionWithCallbackInSandbox = vm.run('module.exports = function(who, callback) { callback("hello "+ who); }');
functionWithCallbackInSandbox('world', (greeting) => {
    console.log(greeting);
});

When wrapper is set to none, NodeVM behaves more like VM for synchronous code.

assert.ok(vm.run('return true') === true);

TIP: See tests for more usage examples.

Loading modules by relative path

To load modules by relative path, you must pass the full path of the script you're running as a second argument to vm's run method if the script is a string. The filename is then displayed in any stack traces generated by the script.

vm.run('require("foobar")', '/data/myvmscript.js');

If the script you are running is a VMScript, the path is given in the VMScript constructor.

const script = new VMScript('require("foobar")', {filename: '/data/myvmscript.js'});
vm.run(script);

Resolver

A resolver can be created via makeResolverFromLegacyOptions and be used for multiple NodeVM instances allowing to share compiled module code potentially speeding up load times. The first example of NodeVM can be rewritten using makeResolverFromLegacyOptions as follows.

const resolver = makeResolverFromLegacyOptions({
    external: true,
    builtin: ['fs', 'path'],
    root: './',
    mock: {
        fs: {
            readFileSync: () => 'Nice try!'
        }
    }
});
const vm = new NodeVM({
    console: 'inherit',
    sandbox: {},
    require: resolver
});

VMScript

You can increase performance by using precompiled scripts. The precompiled VMScript can be run multiple times. It is important to note that the code is not bound to any VM (context); rather, it is bound before each run, just for that run.

const {VM, VMScript} = require('vm2');

const vm = new VM();
const script = new VMScript('Math.random()');
console.log(vm.run(script));
console.log(vm.run(script));

It works for both VM and NodeVM.

const {NodeVM, VMScript} = require('vm2');

const vm = new NodeVM();
const script = new VMScript('module.exports = Math.random()');
console.log(vm.run(script));
console.log(vm.run(script));

Code is compiled automatically the first time it runs. One can compile the code anytime with script.compile(). Once the code is compiled, the method has no effect.

Error handling

Errors in code compilation and synchronous code execution can be handled by try-catch. Errors in asynchronous code execution can be handled by attaching uncaughtException event handler to Node's process.

try {
    var script = new VMScript('Math.random()').compile();
} catch (err) {
    console.error('Failed to compile script.', err);
}

try {
    vm.run(script);
} catch (err) {
    console.error('Failed to execute script.', err);
}

process.on('uncaughtException', (err) => {
    console.error('Asynchronous error caught.', err);
});

Debugging a sandboxed code

You can debug or inspect code running in the sandbox as if it was running in a normal process.

  • You can use breakpoints (which requires you to specify a script file name)
  • You can use debugger keyword.
  • You can use step-in to step inside the code running in the sandbox.

Example

/tmp/main.js:

const {VM, VMScript} = require('.');
const fs = require('fs');
const file = `${__dirname}/sandbox.js`;

// By providing a file name as second argument you enable breakpoints
const script = new VMScript(fs.readFileSync(file), file);

new VM().run(script);

/tmp/sandbox.js

const foo = 'ahoj';

// The debugger keyword works just fine everywhere.
// Even without specifying a file name to the VMScript object.
debugger;

Read-only objects (experimental)

To prevent sandboxed scripts from adding, changing, or deleting properties from the proxied objects, you can use freeze methods to make the object read-only. This is only effective inside VM. Frozen objects are affected deeply. Primitive types cannot be frozen.

Example without using freeze:

const util = {
    add: (a, b) => a + b
}

const vm = new VM({
    sandbox: {util}
});

vm.run('util.add = (a, b) => a - b');
console.log(util.add(1, 1)); // returns 0

Example with using freeze:

const vm = new VM(); // Objects specified in the sandbox cannot be frozen.
vm.freeze(util, 'util'); // Second argument adds object to global.

vm.run('util.add = (a, b) => a - b'); // Fails silently when not in strict mode.
console.log(util.add(1, 1)); // returns 2

IMPORTANT: It is not possible to freeze objects that have already been proxied to the VM.

Protected objects (experimental)

Unlike freeze, this method allows sandboxed scripts to add, change, or delete properties on objects, with one exception - it is not possible to attach functions. Sandboxed scripts are therefore not able to modify methods like toJSON, toString or inspect.

IMPORTANT: It is not possible to protect objects that have already been proxied to the VM.

Cross-sandbox relationships

const assert = require('assert');
const {VM} = require('vm2');

const sandbox = {
    object: new Object(),
    func: new Function(),
    buffer: new Buffer([0x01, 0x05])
}

const vm = new VM({sandbox});

assert.ok(vm.run(`object`) === sandbox.object);
assert.ok(vm.run(`object instanceof Object`));
assert.ok(vm.run(`object`) instanceof Object);
assert.ok(vm.run(`object.__proto__ === Object.prototype`));
assert.ok(vm.run(`object`).__proto__ === Object.prototype);

assert.ok(vm.run(`func`) === sandbox.func);
assert.ok(vm.run(`func instanceof Function`));
assert.ok(vm.run(`func`) instanceof Function);
assert.ok(vm.run(`func.__proto__ === Function.prototype`));
assert.ok(vm.run(`func`).__proto__ === Function.prototype);

assert.ok(vm.run(`new func() instanceof func`));
assert.ok(vm.run(`new func()`) instanceof sandbox.func);
assert.ok(vm.run(`new func().__proto__ === func.prototype`));
assert.ok(vm.run(`new func()`).__proto__ === sandbox.func.prototype);

assert.ok(vm.run(`buffer`) === sandbox.buffer);
assert.ok(vm.run(`buffer instanceof Buffer`));
assert.ok(vm.run(`buffer`) instanceof Buffer);
assert.ok(vm.run(`buffer.__proto__ === Buffer.prototype`));
assert.ok(vm.run(`buffer`).__proto__ === Buffer.prototype);
assert.ok(vm.run(`buffer.slice(0, 1) instanceof Buffer`));
assert.ok(vm.run(`buffer.slice(0, 1)`) instanceof Buffer);

CLI

Before you can use vm2 in the command line, install it globally with npm install vm2 -g.

vm2 ./script.js

Known Issues

  • There are known security issues to circumvent the sandbox.
  • It is not possible to define a class that extends a proxied class. This includes using a proxied class in Object.create.
  • Direct eval does not work.
  • Logging sandbox arrays will repeat the array part in the properties.
  • Source code transformations can result a different source string for a function.
  • There are ways to crash the node process from inside the sandbox.

Deployment

  1. Update the CHANGELOG.md
  2. Update the package.json version number
  3. Commit the changes
  4. Run npm publish

Sponsors

Integromat

vm2's People

Contributors

alizain avatar azu avatar balidani avatar bespokebob avatar blakebyrnes avatar bvanrijn avatar dependabot[bot] avatar donothingloop avatar dorapocket avatar dotconnor avatar franklinyu avatar h0ru5 avatar harelmo avatar iblech avatar kylegoetz avatar leo7654 avatar nick-klaviyo avatar orta avatar patricke94 avatar patriksimek avatar randalpinto avatar rokoroku avatar shigma avatar tabone avatar thanarie avatar undeflife avatar vunovati avatar wojpawlik avatar xmiliah avatar y21 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  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  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

vm2's Issues

Object [object Object] has no method 'isNull'

I use nodejs 0.11.14 and have found an issue during test code snippet calling:

object Object:22
if (ut.isNull(value)) {
^
TypeError: Object object Object has no method 'isNull'
at [object Object]:22:16
at [object Object]:222:17
at Context. (object Object:390:9)

I didn't find isNull() method in util module API.

question about running scripts in vm2

First off, thanks so much for all your work on vm2. Huge fan! Quick question:

My use case for executing these scripts requires that they are, as securely as possible, sandboxed. I know there are always edge cases and potential vulnerabilities, but one of the major ones we have right now when using vm2 is that it doesn't spawn a sub process to execute in. This makes it pretty easy to right a script that just uses a ton of memory and causes our node process to die. As I have looked at some of the other libraries out there (sandcastle, sandbox, jailed, etc.) they seem to spawn child process to protect against something like this. I was just curious if you had attempted this at all with vm2? I'm more than willing to fork the repository and implement myself, but before doing so, I was just curious if you had any insight.

Thanks again!

Promises / callbacks and exported script methods : Is it safe ?

Is it safe to:

  • pass a promise to an exported script method ?
  • receive a promise from a call to an exported script method ?

And more generally : is it safe to pass/receive a callback to/from an exported script method (not through the sandbox, that is) ?

node vm module API changes

Hi, just heard of some v8 developer talked about API changes in the coming node 8.0. Do you know about the details? Will vm2 be affected?

screen shot 2017-02-17 at 6 21 44 pm

Requiring a native module twice, fails

When I try to load a certain native module twice I get a strange exception.

VMError: Failed to load '<...>/deasync.node': [Module did not self-register.]

Here's a minimal example, which shows the problem. (Requires the npm module 'deasync' to run).

//Look up module path for this platform:
var path = require('path');
var fs = require('fs');

var nodeV = 'node-' + /[0-9]+\.[0-9]+/.exec(process.versions.node)[0];
var nodeVM = 'node-' + /[0-9]+/.exec(process.versions.node)[0];
var modPath = path.join(__dirname,'node_modules','deasync', 'bin', process.platform + '-' + process.arch + '-' + nodeV, 'deasync');

try{
    fs.statSync(modPath + '.node');
}
catch(ex){
    modPath = path.join(__dirname, 'node_modules','deasync','bin', process.platform + '-' + process.arch + '-' + nodeVM, 'deasync');
    fs.statSync(modPath + '.node');
}

//Beginning of the actual problem:

require(modPath); //Require native module for the first time

const NodeVM = require('vm2').NodeVM;
const vm = new NodeVM({
    require: true,
    requireExternal: true
});

vm.run("module.exports = require("+JSON.stringify(modPath)+")"); //Require module for the 2nd time, now inside vm.

//Exception occurs: VMError: Failed to load '<...>/deasync.node': [Module did not self-register.]
//Exception occurs as well if we require the same native module in two separate instances of NodeVm.

console.log won't work

No matter what options I set, console is undefined all the time.

ReferenceError: console is not defined

Trying with following Options: inherit, redirect

does timeout work?

When I run any code, timeout doesn't seemt to work. This just keeps running:

const VM = require('vm2').VM
const vm = new VM({
  timeout: 1000,
  sandbox: {
    mineflayer: require('mineflayer')
  }
})

vm.run(`
var bot = mineflayer.createBot({
    host: "localhost",
    port: "25565",
    username: "Bot",
    password: null
})

bot.on('login', function() {
    bot.chat('hi everyone!')
})
`)

Getting returned value

I run a NodeVM
var result = vm.run('1+1') (just an example)
but result becomes just an empty object.
how can I get the returned value, like I would from doing var result = eval('1+1')?

Handle error in async callback

Is there any way to handle error in async callback?

const {NodeVM} = require('vm2');

const vm = new NodeVM({
    timeout: 10000,
    sandbox: {}
});

try {
  vm.run(`
    setInterval(() => {
      console.log("haha")
      process.exit()              // <--- can't find a way to intercept this!
    }, 1000);

    process.exit()
  `, 'code.js');
} catch(e) {
  console.log(e.message);
}


setInterval(() => {
  console.log("haha 2")
},1000);

I'm seeking for a way to prevent whole script crashing.

kill vm

is there a way to kill a vm, once it's started?

question: sandboxing strategies for broken versions of node

Thanks for this module. I apologize that this is more of a general question; if you know of a good community to ask this in, please let me know. I'm pretty sure this is too specific for Stack Overflow.

I was attempting to use vm2 in AWS Lambda; unfortunately Lambda is locked to Node.js v4.3.x at the time of this writing. I'm aware vm2@2.x supports this version, but see nodejs/node#3113. I don't believe I can leverage vm2 to do what I'm describing below?

To work around the very real and expensive leaks--since contextified sandboxes don't seem to get garbage collected--I've had to create a singleton sandbox. The sandbox must allow users to access a few select 3p libraries, and must allow asynchronous behavior.

Roughly, the strategy is:

  1. Create an object via Object.create(null); contextify it w/ vm.createContext()
  2. Create a child object (call it child) via Object.create(null); put it in the contextified sandbox & re-create for each Lambda call. This is the only property of the contextified sandbox (as far as I'm aware!)
  3. Place a callback function (e.g. "done(err)") in child, which will be called when the possibly async untrusted code is done executing. Bind it to null; re-create it for each Lambda call
  4. Place a reference to a require() in child; re-create for each Lambda call
  5. Use JSON.stringify() to put other information into child; this information contains a list of 3p modules to require, among other things. The idea here is to avoid exposing objects created by the the script calling vm.runInContext()--as has been shown to be accessible thru trickery in #32. Re-create for each call
  6. Note that everything above originates in the calling Lambda function. Wrap the untrusted code with a script which synchronously:
    1. Calls require() to include necessary 3p modules; exposes these vetted modules to untrusted script
    2. Saves reference to callback function within a closure (this reference is the only vestige of the calling script's context still present upon untrusted script execution that I'm aware of)
    3. Parses any other JSON data
    4. Creates a wrapper for the callback which sanitizes any errors supplied by user. The user cannot "return" data otherwise from the untrusted script
    5. Nullifies and deletes the entire contents of child to be defensive
  7. Further wrap untrusted script in a closure, passing the callback wrapper function as done, null as parameter child (which should overwrite the only available property of the sandbox), and other data & modules as parameters; these become what the user perceives to be "globals". Prepend 'use strict'
  8. Execute the untrusted code (vm.runInContext()) and end function after it calls done() (it must call done())

Given the Broadway production I had to put on to avoid crippling memory leaks, does this sound reasonably sane? Any obvious holes? I've learned from #32 that putting objects willy-nilly in the sandbox is exposing too much surface, so I've attempted to completely avoid it. And yes, it's very ugly, if you're curious.

(FWIW, I haven't found any concurrency-related issues with data bleeding into other functions while testing; not sure what kind of performance penalties this will end up incurring, but I'll take that over the memory leaks. An alternative is to run the untrusted scripts in worker processes, which sounds even slower)

timeout not work

Hi.
If unsafe code contain setInterval then timeout for VM is not work.

Example:

const {VM} = require('vm2');

const vm = new VM({
timeout: 1000,
sandbox: {
setInterval: setInterval
}
});

try {
vm.run("setInterval(function(){},100)")
} catch (e) {
console.log(e);
}

Can sandbox code execute host function safely?

based on issues like the ones mentioned in

#32

I would like to know if I can actually call a host function safely from the sandbox? an example:

const {VM} = require('vm2');
function hostFunction() {
    //for example, allow HTTP get from a single url, without giving full access to HTTP package
    console.log('host function called from inside sandbox');
}
let sandbox = {
    hostFunction: hostFunction
}
let vm = new VM({ sandbox });
vm.run(`hostFunction();`)

DOCS: Async implementation

@patriksimek thanks for working on a safe sandbox.

I'm looking for some docs on how to return sandbox results asynchronously

Do you have any advice or examples?

I have the following suggestion below. However I see that the callback environment will be different than the sandbox env. This should normally be ok. Is there a way around this?

const {NodeVM} = require('vm2');
const request = require('request');

const vm = new NodeVM({
    sandbox:{
      request: request,
    }
});

let functionInSandbox = vm.run(`module.exports =  function(callback) {
  console.log('sandbox process env', process.env) ;

  request('http://google.com', function (error, response, body) {

        if (!error ) {
            callback( response.statusCode )
        }
    })
}`);

callbackFunc = function( result ){
  console.log('result after async', result);
  console.log('callback process env', process.env) ;
}

functionInSandbox( callbackFunc )

Not immune to while(1) in getters

Consider following code as example to reproduce bug:

var VM = require('vm2').VM,

// Case 1:
var vm1 = new VM({
    timeout: 5000
});

// Works correct, throws exception
vm1.run('while(1);')

// Case 2:
var vm2 = new VM({
    timeout: 5000,
    sandbox: {
        a: {
            get b () {
                while(1);
                return 1;
            }
        }
    }
});

// Not stopping from looping, too bad!
vm2.run('a.b')

Actualy, that will happen, when exectuing any code inside run(), having that getter inside sandbox because of main.js:79.

Of course, i can find a workaround here, but i suppose, that sandbox can contain something untrusted either.

node6 requirement

Tried using this in an AWS lambda and got a warning about requiring node 6. Thinking that should be made explicit in the README.

Add memory constraints to vm2

It would be very useful to insert a memory limit into vm2 options, so that process gets killed if limit is passed.

Limit access to built-in modules

Got excited looking at the ability to have control on limiting a user script from accessing built-in modules.

The access denial works for only one level, if an user script loads an other module which indeed access built-in module then no checks are done.

Here is a simple example for the scenario that I am talking about:

STEP 1 :: Create a main.js file which executes sampleOne.js in a sandbox.

var fs = require('fs')
const {NodeVM} = require('vm2');
const vm = new NodeVM({
    console: 'inherit',
    sandbox: {},
    require: {
        external: true,
        builtin: ['path'],
        root: "./",
        mock: {
        }
    }
});
var scriptContent = fs.readFileSync('./sampleOne.js');
vm.run(scriptContent, 'sampleOne.js');

STEP 2 :: Create sampleOne.js file with following content which invokes an other module.

var sampleTwo = require('./sampleTwo.js');
var fileName = 'sampleTwo.js';
console.log('SampleOne:: Invoke sampleTwo printFileContent:' + fileName);
sampleTwo.printFileContent(fileName); 

STEP 3:: Create sampleTwo.js which will access built-in "fs" module to read a file content.

var fs = require('fs');
exports.printFileContent = function(fileName) {
    console.log('SampleTwo:: print content of file: ' + fileName);
    var fileContent = fs.readFileSync(fileName)
    console.log('\n\nfs module is accessible.\n');
}

STEP 4:: Execute main.js and in the output we can see that sampleTwo.js file can read its own file content using fs module.

ksingh-mac:test ksingh$ node main.js 
SampleOne:: Invoke sampleTwo printFileContent:sampleTwo.js
SampleTwo:: print content of file: sampleTwo.js
fs module is accessible.

When I try to access fs module in sampleOne.js, there is a proper error message saying:

VMError: Access denied to require 'fs'
    at _require (/Users/ksingh/projects/tekton/nodejs/node_modules/vm2/lib/sandbox.js:178:13)
    at Object.<anonymous> (/Users/ksingh/projects/tekton/nodejs/test/sampleOne.js:1:72)
    at NodeVM.run (/Users/ksingh/projects/tekton/nodejs/node_modules/vm2/lib/main.js:301:27)
    at Object.<anonymous> (/Users/ksingh/projects/tekton/nodejs/test/main.js:17:4)
    at Module._compile (module.js:541:32)
    at Object.Module._extensions..js (module.js:550:10)
    at Module.load (module.js:458:32)
    at tryModuleLoad (module.js:417:12)
    at Function.Module._load (module.js:409:3)
    at Function.Module.runMain (module.js:575:10)

Is there any other setting that needs to be done on NodeVM to deny access for built-in modules for nested files.

Note: I am using node v6.2.0.

Error: Unknown encoding: 5406

Guys, lib doesn't work with node >= 4.0

> nvm use 4.0
> npm test
> /Users/Shopgate/shopgate/fcs-worker/node_modules/vm2/node_modules/mocha/lib/reporters/base.js:168
      , stack = err.stack || message
                   ^

Error: Unknown encoding: 5406
  at assertEncoding (fs.js:88:11)
  at Object.fs.readSync (fs.js:594:5)
  at Object.fs.readSync (/Users/Shopgate/shopgate/fcs-worker/node_modules/vm2/node_modules/mocha/node_modules/glob/node_modules/graceful-fs/polyfills.js:218:23)
  at Object.fs.readFileSync (fs.js:433:24)
  at Object.exports._compileFile (/Users/Shopgate/shopgate/fcs-worker/node_modules/vm2/node_modules/coffee-script/lib/coffee-script/coffee-script.js:224:14)
  at getSourceMap (/Users/Shopgate/shopgate/fcs-worker/node_modules/vm2/node_modules/coffee-script/lib/coffee-script/coffee-script.js:343:22)
  at getSourceMapping (/Users/Shopgate/shopgate/fcs-worker/node_modules/vm2/node_modules/coffee-script/lib/coffee-script/coffee-script.js:351:19)
  at formatSourcePosition (/Users/Shopgate/shopgate/fcs-worker/node_modules/vm2/node_modules/coffee-script/lib/coffee-script/coffee-script.js:303:16)
  at /Users/Shopgate/shopgate/fcs-worker/node_modules/vm2/node_modules/coffee-script/lib/coffee-script/coffee-script.js:369:33
  at Function.Error.prepareStackTrace (/Users/Shopgate/shopgate/fcs-worker/node_modules/vm2/node_modules/coffee-script/lib/coffee-script/coffee-script.js:372:7)
  at /Users/Shopgate/shopgate/fcs-worker/node_modules/vm2/node_modules/mocha/lib/reporters/base.js:168:20
  at Array.forEach (native)
  at Function.exports.list (/Users/Shopgate/shopgate/fcs-worker/node_modules/vm2/node_modules/mocha/lib/reporters/base.js:159:12)
  at Spec.Base.epilogue (/Users/Shopgate/shopgate/fcs-worker/node_modules/vm2/node_modules/mocha/lib/reporters/base.js:312:10)
  at emitNone (events.js:72:20)
  at Runner.emit (events.js:166:7)
  at Runner.uncaught (/Users/Shopgate/shopgate/fcs-worker/node_modules/vm2/node_modules/mocha/lib/runner.js:563:8)
  at process.uncaught (/Users/Shopgate/shopgate/fcs-worker/node_modules/vm2/node_modules/mocha/lib/runner.js:580:10)
  at emitOne (events.js:77:13)
  at process.emit (events.js:169:7)
  at process._fatalException (node.js:211:26)

npm ERR! Test failed.  See above for more details.

Switching to 0.12 makes everything ok

TypeError: 'get' on proxy: property 'constants' is a read-only and non-configurable data property on the proxy target but the proxy did not return its actual value

Noticed this while trying to require a dependency in a vm. Some code to reproduce:

const { NodeVM } = require("vm2");

const vm = new NodeVM({
  console: "redirect",
  sandbox: {},
  require: {
    builtin: ["fs"]
  },
  wrapper: "none"
});

vm.run("const fs = require('fs'); fs.constants");

Full stack trace:

node_modules/vm2/lib/main.js:327
			throw this._internal.Decontextify.value(e);
			^
TypeError: 'get' on proxy: property 'constants' is a read-only and non-configurable data property on the proxy target but the proxy did not return its actual value (expected '[object Object]' but got '[object Object]')
    at Object.<anonymous> (vm.js:1:91)
    at NodeVM.run (node_modules/vm2/lib/main.js:325:27)
    at Object.<anonymous> (script.js:12:4)
    at Module._compile (module.js:556:32)
    at Object.Module._extensions..js (module.js:565:10)
    at Module.load (module.js:473:32)
    at tryModuleLoad (module.js:432:12)
    at Function.Module._load (module.js:424:3)
    at Module.runMain (module.js:590:10)
    at run (bootstrap_node.js:394:7)

Let me know if there's any other information I can give you to be helpful!

"new Uint8Array(1e+100)" causes hang

If you run "new Uint8Array(1e+100)" or with another large number, the sandbox hangs. The event loop is blocked, and the whole process freezes.

setTimeout and setInterval not working?

I just saw that setTimeout and setInterval are not working inside the VM. I am using version 3.0.0.

Example 1:

const {NodeVM} = require('vm2');
let vm = new NodeVM();
vm.run('setTimeout(function(){console.log(12345)}, 10000);');

Instead of printing 12345 after 10s this prints it immediately.

Example 2:

const {NodeVM} = require('vm2');
let vm = new NodeVM();
vm.run('let counter = 0; function foo(){console.log(counter++);} setInterval(foo, 5000);');

Instead of increasing and printing the counter every 5s it does it what seems like every millisecond.

I didn't see any comment in the documentation that those functions do not work. Is this a bug or did I overlook something?

Advantages over the native VM module

Hello there :)

Just wanted to know if there are clear advantages using vm2 over node's native VM module -- tried to look for it in the readme but couldnt find anything. I'm using vm on node 7 and was wondering if I should potentially look at vm2 if it fixes / handles specific use-cases.

Cheers!

How to use/call 'require'

Hi

I'm trying to use vm2 in order to allow user written scripts which run in vm2 to use 'require'. I added

var request = require('request')

to the top of my 'userScript' and then added the userScript to vm2's sandbox. When I try and run the vm by doing ...

var result = vm2.run(helper)

my node process crashes with a 'require is not defined' error.

How do I call 'require' statements in user scripts ?

More details on this question can be found in another question (#20)

Thanks
Dave

VMError: Access denied to require 'module', mongoose

I will use your VM module to make my code more modular.

When i youse mongoose inside the VM i got a "Access Denied" error:
VMError: Access denied to require 'module'

    // read source from module
    var module = that.modules[key];
    var source = fs.readFileSync(module.path, "utf8");

    // vm options
    var options = {
      console: 'inherit',
      sandbox: {
        log: module.log
      },
      require: true,
      requireExternal: true,
      //requireNative: "",
      requireRoot: "./",
      useStrict: false

    };

    // create vm & run
    var vm = new NodeVM(options);
    var moduleEntry = vm.run(source, module.path);

    moduleEntry(that.injector);

  });

What does console: 'redirect' mean

I wanted to know what you mean by "redirect to events" when using the redirect option for console in NodeVM. I have always used the sandbox method, of just attaching a console object with its own methods, however I wanted to know if there was an alternative cleaner solution

Restriction does not affect requiring in modules

Hi,

first of all. Thank you for v3! Its really really amazing.

Unfortunately I found another bug.
It is possible to require restricted native modules in required modules.

For example:
Lets say the code in the vm want to get a file from the filesystem.

The way via fs works fine:

var NodeVM = require('vm2').NodeVM;

var options = {
    console: 'inherit',
    require: {
        external: true,
        builtin: [],
        root: "./"
    },
    nesting: true

};

var vm = new NodeVM(options);
var functionInSandbox = vm.run("module.exports = function(){  var fs = require('fs');  fs.readFile('./node_modules/vm2/index.js', function (err, data) { console.log(err, ''); }); }", __filename);
vm.call(functionInSandbox);

It throws me an error which is correct.

But lets use one random fs module from npmjs:

var NodeVM = require('vm2').NodeVM;

var options = {
    console: 'inherit',
    require: {
        external: true,
        builtin: [],
        root: "./"
    },
    nesting: true

};

var vm = new NodeVM(options);
var functionInSandbox = vm.run("module.exports = function(){  var read = require('read-file');  read('./node_modules/vm2/index.js', function (err, data) { console.log(err, data.toString('utf-8')); }); }", __filename);
vm.call(functionInSandbox);

This time I can read the complete file.

It looks like that the require method in the modules are not restricted.

Separation of contextification from script compilation

Node's VM module allows to compile a script with vm.Script() and at a later point contextify it with a number of different functions (e.g. script.runInNewContext). This is handy when one need to run the same exact code in multiple contexes. I presume that VM2 compiles the string-code every time vm.run() is called. I expect that this would result in performance degradation.

Would it be a good idea for VM2's API to support some soft of way to reused a compiled piece of code multiple times across contexes? Is there a work-around to do this today?

Escaping the vm sandbox

It's possible to escape the VM and perform very undesirable actions.

Found via the following gist in relation to node's native VM: https://gist.github.com/domenic/d15dfd8f06ae5d1109b0

Take the following 2 code examples:

const VM = require('vm2').VM;

const options = {
    sandbox: {}
};

const vm = new VM(options);

vm.run(`
    const ForeignFunction = global.constructor.constructor;
    const process1 = ForeignFunction("return process")();
    const require1 = process1.mainModule.require;
    const console1 = require1("console");
    const fs1 = require1("fs");
    console1.log(fs1.statSync('.'));
`);

and :

const NodeVM = require('vm2').NodeVM;

const options = {
    console: 'off',
    sandbox: {},
    require: false,
    requireExternal: false,
    requireNative: [],
    requireRoot : "./"
};

const vm = new NodeVM(options);
vm.run(`
    const ForeignFunction = global.constructor.constructor;
    const process1 = ForeignFunction("return process")();
    const require1 = process1.mainModule.require;
    const console1 = require1("console");
    const fs1 = require1("fs");
    console1.log(fs1.statSync('.'));
`);

Running either of these outputs the following:

{ dev: 16777220,
  mode: 16877,
  nlink: 14,
  uid: 502,
  gid: 20,
  rdev: 0,
  blksize: 4096,
  ino: 14441430,
  size: 476,
  blocks: 0,
  atime: 2016-06-15T22:20:05.000Z,
  mtime: 2016-06-15T22:19:59.000Z,
  ctime: 2016-06-15T22:19:59.000Z,
  birthtime: 2016-06-09T01:02:12.000Z }

I've validated this behavior on both v4.4.5 and v6.2.1

Access denied to require 'module'

With babel-register module

    var renderVM = new NodeVM({
        console:         'inherit',
        require:         true,
        requireExternal: true,
        requireNative:   [ 'path', 'fs', 'util', 'tty', 'module' ],
        sandbox: {
            process: { argv: [], env: {} },
            __babel: sails.config.babel
        }
    });

    console.log(renderVM.run(`
        require("babel-register")(__babel);
        module.exports = require("../../../editor/app/render/render").default;
    `, __filename));

Exiting/closing a VM

I'm creating multiple VM's in my script and I want to close/kill them and free up their resources as soon as their work is done.

I checked the tests and the script in there is just setting the vm variable to null, allowing the vm object to be garbage collected by js.

Is this is the appropriate way of exiting a VM? And does it free up the resources allocated to the VM?

A custom compiler/transformer is ignored by require()

If you set the compiler option to be coffee script or a custom function it will only be used to transform the main file you're running. If the main file includes other scripts, they won't be transformed.

As you can see in sandbox.js, line 50 the required file is not passed through _compileToJS() before being executed.

Documentation for sandbox using vm2

Is there a way to set up the sand box such that the parent script launching the child script can pass objects by reference to the child script so that it can call into the objects/methods? There is very thin documentation on sandbox for vm2 hence the question. I tried something like

var VM = require('vm2').VM;
var localvar = 'foo';
var localvar2 = 'bar';
function myobj(input)
{
this.localvar= = input;
}

var options = {
timeout : 1000,
sandbox: {myobj, localvar2}
};

var vm = new VM(options);
vm.run('myobj(localvar2);');

This does not give me the desired result. Any pointers would be very much appreciated.

Also would be good to know why the sanbox offered by vm2 is better than the sandbox from node.js

[TypeError: Invalid non-string/buffer chunk] occure when http request will be made after NodeVM run

Hi,

when I do a HTTP Request after a run of the NodeVM the following Error appears.

TypeError: Invalid non-string/buffer chunk
    at chunkInvalid (_stream_readable.js:372:10)
    at readableAddChunk (_stream_readable.js:124:12)
    at Socket.Readable.push (_stream_readable.js:110:10)
    at TCP.onread (net.js:523:20)

Here is my code:

var NodeVM = require('vm2').NodeVM;
var request = require('request');

var options = {
    console: 'inherit',
    require: true,
    requireExternal: true,
    requireNative: [],
    requireRoot : "./"
};

var vm = new NodeVM(options);
var functionInSandbox = vm.run("module.exports = function(){  console.log('Output from function in sandbox'); }", __filename);
vm.call(functionInSandbox);


request('http://google.com', function (err, response, body) {
    if (err) {
        console.error(err.stack);
        return;
    }
    console.log(body);
});

My node version is 4.3.0

When I remove the 'vm.run' and the 'vm.call' the request works.
I already look into the code but i cant find the reason why this happens but i cant find any reason why :(

Locking up the host

Using promises (or similar async callbacks), one can circumvent the timeouts:

var vm = new vm2({
    timeout: 10,
    sandbox: {}
});
vm.run("new Promise((r,j)=>r()).then((v)=>{while(true);})")

The while(true) code is not time limited at all and will lock up the entire node.js process.
For simplicity, a non-shortened version of the code in the string:

new Promise( (resolve, reject) => resolve() )
.then( function(value) {
    while(true);
}

Is there some fail safe way to fix/prevent this? Or is this an intrinsic problem of how node.js vm works? Obviously, doing

sandbox: { Promise: null }

prevents the user from creating promises, but as long as the user has access to any kind of async code, he can crash the VM.

Only disallow require of specific local files

I want to allow requiring of all modules/files except specific files in an array. I am trying to block access to APIs in a secure system.

Also, does this block requires of requires (i.e. the module originally required requires a file that requires restricted module).

Lastly, can someone run a child process that runs the CLI version of my app? I want to allow access to CLI programs (child processes) except for mine.

Continuous communication with the sandbox

This is not an issue with vm2 itself, but a question about functionality (and perhaps to extend the docs with examples):

I have a scenario where I want to use a sandbox/jail to run long-lived untrusted code (similar to a Web Worker). The code should use an API to both listen to events from an outside system and respond by performing simple actions restricted by the API (aka Macros). Optimally, these snippets of code supplied by system administrators should only have access to this API and not much else. I don't mind the untrusted code hogging the event loop (e.g. while (true) {}) for the time being.

What are the options for having event-driven input and output between the sandbox context and the outside world? The API in question uses an underlaying Duplex stream of JSON data, which would be nice to proxy/relay into the sandbox. E.g. connecting (via methods/callbacks if necessary) a global and a contextified stream would most likely be sufficient. Would vm2 be able to support this in a way? Could you provide any thoughts/input on a minimal viable example for this?

vm.run() without filename dies when encountering an external require

const vm = new NodeVM({                   
  require: true,                          
  requireExternal: true                   
});                                       

vm.run('console.log(require("foobar"));');

fails with:

sandbox.js:121                                  
          paths = current_dirname.split(pa.sep);

TypeError: Cannot read property 'split' of null

Meanwhile, passing a second parameter to vm.run(..., filename) works. Reading the code indicates that filename should be rather optional.

Add timeout option to NodeVM

Is there a reason why the "timeout" option is not implemented for the NodeVM case (since it is available for regular VM)?
I think it would be a nice improvement to the possibilities.

Is this something that is going to be added in the future?

Question about running js script in vm2

Hi

Using Node's built-in vm - I can do the following ...

var userScript = 'var dummy = 0;' ; // note userScript contains javascript code 
var helper = 'if (dummy > 10) { console.log("time to stop"); } else { console.log("keep going"); }" ;

var sandbox = {
  userScript: userScript
};
var context = vm.createContext(sandbox);
var script = new vm.Script(helper);

script.runInContext(context);

Essentially - I have a user supplied javascript script along with a 'helper' script that also contains javascript. I 'combine' these two scripts when I say "script.runInContext(context)".

Can I do the same thing using vm2 and if so - how ?

Thanks
Dave

while(true) still blocks execution when using NodeVM

When using NodeVM in combination with vm.call(methodname, params), a "while(true)" statement still blocks execution. Am i doing something wrong or is this a bug?

My code:

    // sandbox properties
    var options = {
      console: 'inherit',
      sandbox: {
        "var1": var1,
        "var2": var2
      },
      require: true,
      requireExternal: false,
      requireNative: [],
      timeout: 100 // see my other issue, since this is not working
    };
    var vm = new NodeVM(options);
    var script= vm.run("module.exports = { onLoad: function(){ while(true);}}");

    vm.call(script.onLoad); // this blocks execution

Quick Question

How do I use this module to execute untrusted code securely and wait for a return data? The return data can be a JSON Document.

Would you be able to provide a sample gist for the use case above? Thanks!

Use child_process to keep the hand on the master process?

Hi,

It is just a question, but, in order to keep the hand on the master process and avoid while(true){}, why no use a child process?

I'm kind of new with the sandbox and vm systems.

Here is my code:

//index.js
'use strict';

let child_process = require('child_process');

setInterval(function(){
    console.log('alpha');
}, 1000);

var child = child_process.fork('startCode.js');

setTimeout(function(){
    child.kill();
}, 10000);
//startCode.js
'use strict';

const NodeVM = require('vm2').NodeVM;

const vm = new NodeVM({
    console: 'inherit',
    sandbox: {},
    require: {
        external: true,
    }
});

setInterval(function(){
    console.log('alpha2'); 
}, 1000); //never shown do to infinite loop

let functionInSandbox = vm.run("while(true){}");

What do you think about it?

readline as script in vm2 throws error on keyDown

I try to execute input from the commandline in a sandbox with vm2.
Unfortunately, after executing one command, I always get an error as soon as I press another key.

L:\tmp>node test.js
> console.log('Hellow World!');
Hellow World!
{}
> events.js:85
throw er; // Unhandled 'error' event
^
TypeError: Invalid non-string/buffer chunk
at chunkInvalid (_stream_readable.js:384:10)
at readableAddChunk (_stream_readable.js:140:12)
at ReadStream.Readable.push (_stream_readable.js:126:10)
at TTY.onread (net.js:538:20)

L:\tmp>

Test script:

'use strict';

var vm = require('vm2');
var readline = require('readline');

var rl = readline.createInterface({

    input: process.stdin,
    output: process.stdout
});

rl.setPrompt('> ');
rl.prompt();

rl.on('line', function ($line) {

    var options = {

        sandbox: {},
        console: 'inherit',
        language: 'javascript',
        require: true,
        requireNative: true,
        requireExternal: true,
    };

    var sb = new vm.NodeVM(options);


    console.log(sb.run($line));
    rl.prompt();
});

Versions:
vm2 - 0.2.2

http_parser - 2.3
node - 0.12.2
v8 - 3.28.73
uv - 1.4.2-node1
zlib - 1.2.8
modules - 14
openssl - 1.0.1m

iojs 3.3.0 and Buffer

Heads up - testing vm2 with the latest iojs has flagged an odd issue with Buffer, probably due to the various V8 changes related to Buffer.

var VM = require('vm2').NodeVM;

var buf1 = new Buffer(1);
console.log('check before VM:', (buf1 instanceof Buffer));

var vm = new VM();
vm.run("console.log('ran VM')");

var buf2 = new Buffer(1);
console.log('check after VM:', (buf2 instanceof Buffer), (buf1 instanceof Buffer));

The output of this is...

Node 0.12.7

check before VM: true
ran VM
check after VM: true true

iojs 3.3.0

check before VM: true
ran VM
check after VM: false true

Buffer is no longer instanceof-able and plays havoc with future API calls e.g. fs.readSync due to this check https://github.com/nodejs/node/blob/8f58fb92fff904a6ca58fd0df9ee5a1816e5b84e/lib/fs.js#L589

With Node4 moving forward from an iojs base, this is probably worth looking at.

Extending require() further

I would like an option which is a function that takes vm2's require as an argument and returns a new function that should be used instead of vm2's require.

Instanciate Function on NodeVM

Hey there,

i had instantiate the running script over VM. Here is an example:

Executed Script

var Server = function Server() {
    this.test = function test() { console.log("HI"); };
};

Instantiate

_vm = new VM({/* ... *});
vm.run(script, _path + '/main.js');
// Instantiate the Class
var Server = new _vm._context.Server();
// Call the method
Sevrer.test();

It's working fine on VM. But i had updated to NodeVM to use require, setTimeout and other,..
But how i can instantiate the Server "class" under NodeVM?

Under _vm._context the Server is not available. I had try to use module.exports, but here, i can't instantiate it. Not over the context and not over the returned value from _vm.run().

The Result is:

TypeError: Server is not a constructor

Can anyone help me?

NodeVM won't recognize custom classes

var vm = require('vm2').NodeVM;

function Data() {
    this.key1 = 'value1';
};

Data.prototype.set = function (field, value) {
    this[field] = value;
};

Data.prototype.get = function (field) {
    return this[field];
};

var sandbox = new vm();

var code = 'module.exports = function (Data) {' +
   'try {' +
      'var data = new Data();' +
      'data.set("key2", "value2");' +
      'return data;' +
   '}' +
   'catch(error) {' +
      'return error;' +
   '}' +
'};'

var fn = sandbox.run(code);
var result = sandbox.call(fn, Data);

console.log(result);

The above code returns an error [TypeError: undefined is not a function]

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.