问题
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
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.
Any ideas?
回答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) return true;
}
return false;
};
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.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();
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();
来源:https://stackoverflow.com/questions/19393599/how-do-i-limit-the-node-repls-access-to-internal-node-modules