如何限制节点代表对内部节点模块的访问? [英] How do I limit the node repl's access to internal node modules?

查看:92
本文介绍了如何限制节点代表对内部节点模块的访问?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在一个上一个问题中,我弄清楚了如何从repl上下文中消除不需要的全局变量.但是,我发现repl可以自动访问所有内部节点模块,而无需使用require.我不知道如何禁用此功能.我什至尝试覆盖repl本身中的模块变量,但这是行不通的.

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 node modules without the use of require. I have no idea how to disable this. I even tried overriding the module variables in the repl itself and it doesn't work.

> fs ="test";
> fs

> fs = "test";
> fs

它仍然显示fs原始值.这是非常不幸的,因为我正试图公开公开代表,但它使他们可以访问整个服务器.

It still displays fs original value. This is very unfortunate because I'm trying to expose a public repl but it gives them access to the entire server.

有什么想法吗?

推荐答案

如您所说,REPL可以访问

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

(但是,经过检查后,我可以用节点0.10.20覆盖它们,因此应该有解决方案)

(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'

更好的方法是在创建repl实例之前覆盖repl._builtinLibs.

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

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

此外,如果您不想公开.save.load之类的命令,将白名单repl命令列为白名单也很简单.

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];

注意:数组通常没有contains方法,因此我添加了一个.

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) return true;
    }
    return false;
};

如果要从repl实例的全局范围中删除变量,请参见此问题.

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

请注意,向公众公开REPL是非常不安全的.

您可以轻松使整个服务器崩溃

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

REPL不会捕获异步回调中发生的错误,并会降低node.js实例.

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

您可以阻止服务器

> while(true) {};

您最好的选择是使用child_process,readline和vm在单独的进程中编写自己的REPL.这是一个起点:

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:

主人:

// master.js
var fork = require('child_process').fork;

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

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

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

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

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

forkRepl();

以及用于repl的单独过程:

and the separate process for the repl:

// child_repl.js
var 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();

这篇关于如何限制节点代表对内部节点模块的访问?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆