Как ограничить экземпляры repl узла, чтобы они не могли получить доступ к глобальной области?

Когда вы создаете новый экземпляр repl в коде, он автоматически получает доступ ко всему в глобальной области видимости. Вы можете изменить контекст repl, чтобы выставить некоторые пользовательские переменные в локальной области видимости, чтобы repl мог получить к ним доступ, но я не вижу простого способа устранить доступ к глобальной области. Хотел бы я дать реплею новую пустую глобальную область видимости.

Вот пример экземпляра repl:

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

В этом реплее я напечатал следующее:

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

Что привело к следующему списку:

  • 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
  • Глобальный
  • процесс
  • ГЛОБАЛЬНЫЙ
  • корень
  • буфер
  • SetTimeout
  • setInterval
  • clearTimeout
  • clearInterval
  • setImmediate
  • clearImmediate
  • приставка
  • модуль
  • требовать
  • тзд
  • _
  • ключ

Вы можете видеть, что наши msg там была добавлена ​​переменная, и это здорово, но есть много глобальных переменных, которые я не хочу раскрывать. Я хочу раскрыть некоторые из менее вредных, таких как setTimeout, consoleи т.д., но определенно не такие вещи, как require, processи т.д. Кто-нибудь знает, как я мог бы преодолеть это, не порождая совершенно новый дочерний процесс?

1 ответ

Решение

Я не знаю, является ли это лучшим решением, но мне удалось это сделать. Объект контекста для repl является глобальным объектом. Это просто автоматически дополняется всем от global, Это означает, что вы можете перебирать свойства и удалять те, которые вам не интересны.

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

Это немного раздражает необходимость поддерживать строковый массив глобальных переменных, которые я хочу разрешить, но, по крайней мере, эти белые списки их. Если узел обновляется и добавляет что-то новое в глобальную область, он не будет отображаться, пока я не добавлю это явно в список.

Если вам необходимо также включить команды repl из белого списка или исключить доступ repl к модулям ядра узла, посмотрите этот вопрос.

Другие вопросы по тегам