How do I limit node repl instances so they cannot access global scope?

谁说我不能喝 提交于 2019-12-24 13:13:14

问题


When you create a new repl instance in code it automatically has access to anything in global scope. You can modify the repl context to expose some custom variables in local scope so that the repl can access them, but I don't see an easy way to eliminate access to the global scope. I wish I could just give the repl a new blank global scope.

Here is an example repl instance:

var repl = require('repl'),
    msg = "Hello world!";
repl.start('> ').context.msg = msg;

In that repl I typed out the following:

for (var key in global) {
    console.log(key);
}

Which resulted in the following list:

  • ArrayBuffer
  • Int8Array
  • Uint8Array
  • Uint8ClampedArray
  • Int16Array
  • Uint16Array
  • Int32Array
  • Uint32Array
  • Float32Array
  • Float64Array
  • DataView
  • DTRACE_NET_SERVER_CONNECTION
  • DTRACE_NET_STREAM_END
  • DTRACE_NET_SOCKET_READ
  • DTRACE_NET_SOCKET_WRITE
  • DTRACE_HTTP_SERVER_REQUEST
  • DTRACE_HTTP_SERVER_RESPONSE
  • DTRACE_HTTP_CLIENT_REQUEST
  • DTRACE_HTTP_CLIENT_RESPONSE
  • COUNTER_NET_SERVER_CONNECTION
  • COUNTER_NET_SERVER_CONNECTION_CLOSE
  • COUNTER_HTTP_SERVER_REQUEST
  • COUNTER_HTTP_SERVER_RESPONSE
  • COUNTER_HTTP_CLIENT_REQUEST
  • COUNTER_HTTP_CLIENT_RESPONSE
  • global
  • process
  • GLOBAL
  • root
  • Buffer
  • setTimeout
  • setInterval
  • clearTimeout
  • clearInterval
  • setImmediate
  • clearImmediate
  • console
  • module
  • require
  • msg
  • _
  • key

You can see that our msg variable was added in there, which is great, but there are many global variables I do not want to expose. I want to expose some of the less harmful ones, such as setTimeout, console, etc, but definitely not things like require, process, etc. Does anyone know how I might overcome this without spawning a totally new child process?


回答1:


I don't know if this is the best solution but I did manage to accomplish this. The context object for the repl is the global object. It's just automatically augmented with everything from global. This means you can iterate over the properties on it and remove the ones you are not interested in.

https://gist.github.com/Chevex/7000130

// Function to determine if an array contains a specific value.
function contains(array, value) {
    for(var i = 0; i < array.length; i++) {
        if(array[i] === value) return true;
    }
    return false;
}

var repl = require('repl'),
    newRepl = repl.start('> ');

var allowedGlobals = ['ArrayBuffer', 'Int8Array', 'Uint8Array', 'Uint8ClampedArray', 'Int16Array', 'Uint16Array', 'Int32Array',
    'Uint32Array', 'Float32Array', 'Float64Array', 'DataView', 'Buffer', 'setTimeout', 'setInterval',
    'clearTimeout', 'clearInterval', 'console', '_'];

for (var key in newRepl.context) {
    if (!contains(allowedGlobals, key)) {
        delete newRepl.context[key];
    }
}

It's kind of annoying having to maintain a string array of global variables I want to allow, but at least this white-lists them. If node updates and adds something new to the global scope it won't be exposed until I explicitly add it to the list.

If you need to also white-list repl commands or eliminate the repl's access to node core modules then see this question.



来源:https://stackoverflow.com/questions/19392483/how-do-i-limit-node-repl-instances-so-they-cannot-access-global-scope

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!