Как ограничить экземпляры 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 к модулям ядра узла, посмотрите этот вопрос.