5

I did a little research and couldn't find anything that makes my case success.

So, I'm loading .js from external scripts with require(..), each script exports a function ..

main.js

var main=10;
var mod1 = require("./mod1.js");

mod1.js

module.exports=function(){
 console.log('loaded');
 var net=require('net'); // i don't want it to be able to require certain node.js apis
 net.create...; 
}

I saw some ways where a .json file declares the permissions and if so it grants access to script. How can something like that be achieved for core node.js apis?

Andrzej Karpuszonak
  • 8,896
  • 2
  • 38
  • 50
Gntem
  • 6,949
  • 2
  • 35
  • 48

1 Answers1

9

Depending on what exactly you want, you might be able use the vm module (which is built-in to Node) as a sort of sandbox thing:

var vm = require('vm');
var fs = require('fs');

var safe_require = function(mod) {
  var code    = fs.readFileSync(require.resolve(mod));
  var sandbox = {
    console : console,
    module  : {},
    require : function(mod) {
      // as a simple example, we'll block any requiring of the 'net' module, but
      // you could implement some sort of whitelisting/blacklisting for modules 
      // that are/aren't allowed to be loaded from your module:
      if (mod === 'net') {
        throw Error('not allowed');
      }
      // if the module is okay to load, load it:
      return require.apply(this, arguments);
    }
  };
  vm.runInNewContext(code, sandbox, __filename);
  return sandbox.module.exports;
};

var mod = safe_require('./mod1');

(as you can see, any built-in functions of Node, like console, that you want to use in the modules that are safe_require'd need to be passed in the sandbox object)

robertklep
  • 198,204
  • 35
  • 394
  • 381
  • That is, but you should always remember that vm api is marked as unstable (http://nodejs.org/api/vm.html). Anyway, it's a lot like eval - you can do cool stuff with it, but you are better to avoid if possible. – vkurchatkin Oct 18 '13 at 08:26
  • @vkurchatkin well, domains, streams and crypto are also unstable :) if there is another way of hooking into `require`, that might obviously be a better solution in this case, but I don't know of any (perhaps [`require.extensions`](http://nodejs.org/api/all.html#all_require_extensions), but that's deprecated) – robertklep Oct 18 '13 at 08:35
  • I also think this is the best solution in this particular case, I was just commenting @Jakob about vm being cool) – vkurchatkin Oct 18 '13 at 09:24
  • that's so awesome, my first first 1st aproach was to create a parser out of jison which pretty much failed! i can work with regexes + vm module so i can achieve better results now. – Gntem Oct 18 '13 at 10:34
  • 1
    You should also add `use strict;` to the head of the code in order to prevent breaking the sandbox using `arguments.callee.caller`. I have recently created [a library](https://github.com/asvd/jailed) for running untrusted code, which additionally simplifies the interaction between the application and sandboxed code. – asvd Jan 18 '15 at 15:06
  • 2
    I noticed that if `mod1` then does `require('net-proxy')` which contains the following code: `module.exports = require('net')`, then `mod1` can still access the net module. So it doesn't seem so safe after all. Is there any way around this? – Phil Mander Sep 12 '15 at 18:59