Skip to content Skip to sidebar Skip to footer

How Do I Limit The Node Repl's Access To Internal Node Modules?

In a previous question I figured out how to eliminate unwanted global variables from the repl context. However, I figured out that the repl automatically has access to ALL internal

Solution 1:

As you said, the REPL has access to core modules.

(however, after checking, I am able to override them with node 0.10.20, so there should be a solution)

> fs> { Stats: [Function], …> fs = 'hello';> fs
'hello'

A better way would be to just override repl._builtinLibs before creating a repl instance.

var repl = require('repl');
repl._builtinLibs = [];
repl.start('> ');

Also, it's fairly trivial to white-list repl commands if you don't want to expose commands like .save or .load.

var allowedReplCmds = ['.break', '.clear', '.help'];

var newRepl = repl.start('> ');
for (var key in newRepl.commands)
    if (!allowedReplCmds.contains(key))
        delete replInstance.commands[key];

Note: Arrays don't normally have a contains method so I added one.

Array.prototype.contains = function(v) {
    for(var i = 0; i < this.length; i++) {
        if(this[i] === v) returntrue;
    }
    returnfalse;
};

If you want to remove variables from the repl instance's global scope see this question.


Please note that it is very unsafe to expose a REPL to the public.

You can easily crash the whole server

> setTimeout(function () { throw'bye bye!'; }, 0);

Errors that happen in async callbacks are not caught by the REPL and bring down the node.js instance.

You can block the server

> while(true) {};

Your best bet would be to code your own REPL in a separate process with child_process, readline and vm. Here's a starting point:

The master:

// master.jsvar fork = require('child_process').fork;

// functions exposed to the replvar replApi = {
  hello: function () {
    return'world!';
  },

  unknown: function () {
    return'unknown';
  }
};

function forkRepl() {
  var repl = fork('./child_repl');

  repl.on('message', function (command) {
    varfun = replApi[command] || replApi.unknown;
     repl.send(fun());
  });

  // restart the repl if it dies
  repl.on('exit', forkRepl);
}

forkRepl();

and the separate process for the repl:

// child_repl.jsvar readline = require('readline'),
    vm = require('vm');

var context = vm.createContext({
  hello: function () {
    process.send('hello');
  }
});

var rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout
});

rl.on('line', function (line) {
  vm.runInContext(line, context, 'repl.vm');
});

process.on('message', function (message) {
  console.log('master:', message);
});

rl.prompt();

Post a Comment for "How Do I Limit The Node Repl's Access To Internal Node Modules?"