2016-11-27 5 views
0

Я реализую изолированную среду JS, которая позволяет пользователям загружать свой JS-код и запускать его на основе набора правил.Безопасное повторное использование изолированных контейнеров Nashorn для изолированных ящиков

Я отключил доступ Java из среды Насхорн и только позволяем получить доступ к некоторым вспомогательным классам для нескольких операций, таких как HTTP запросы, кодирование base64 и т.д.

В настоящее время я создаю ScriptEngine (среду Насхорн) для каждого кода JS добавленного но в нашей среде у нас есть много предопределенных JS-кодов, которые используются большинством наших пользователей. Поскольку создание ScriptEngine дорого, я хочу повторно использовать ScriptEngine s для того же кода кода JS. Допустим, что пользователь загрузил следующий код:

userContext работает аналогично переменных окружения, пользователь устанавливает переменные контекста при загрузке ее код и мы передаем их в функцию main. Поскольку JS-код не имеет какой-либо переменной, отличной от основной, он не имеет состояния, поэтому повторное использование контейнера легко. Однако для следующего блока кода, это не тривиально, чтобы повторно использовать контейнер:

var test = []; 
var main = function(event, userContext) { 
    test.push(1); 
    return event.get('time') + userContext.api_key; 
} 

Я ищу способ абстрагировать локальную переменные для каждого пользователя и повторно использовать среду с различным местным контекстом так что Java будет компилировать JS-код в байт-код Java и один раз и повторно использовать один и тот же байт-код и вызывать его в другом контексте, точно так же как отношение между классами и объектами.

Один из способов сделать это - создать ENGINE_SCOPE для каждого пользователя и изменить привязки при вызове основной функции. Однако я не смог найти способ клонировать ScriptObjectMirror. Мой план состоял в том, чтобы создать новую область, когда пользователь загружает предварительно скомпилированный JS-код и использует его при вызове функции. Однако Nashorn, похоже, не позволяет создавать программные возможности программно.

Другая проблема заключается в том, что JS позволяет изменять глобальные объекты. Пользователь может выполнить следующий блок кода без каких-либо проблем и Object будет null для всех казней:

var test = []; 
var main = function(event, userContext) { 
    Object = null; 
    return event.get('time') + userContext.api_key; 
} 

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

Я знаю, что могут возникнуть другие проблемы с безопасностью для повторного использования контейнеров, и безопасный способ заключается в создании разных контейнеров для каждого JS-кода, загружаемого пользователями. Однако создание среды Nashorn довольно дорого по сравнению с V8, и если в среде исполнения слишком много сред Nashorn, Java заполняет Code Cache, поскольку пытается скомпилировать блоки JS-кода для байт-кода Java. Я также открыт для других предложений по решению этой проблемы.

ответ

0

Я считаю, что ScriptContext объекты будут изолировать каждое исполнение.

ScriptEngine engine = new ScriptEngineManager() 
     .getEngineByName("nashorn"); 

// Set up an isolated context. 
Bindings bindings = engine.createBindings(); 
ScriptContext isolatedContext = new SimpleScriptContext(); 
isolatedContext.setBindings(bindings, ScriptContext.ENGINE_SCOPE); 

// Compile the function in the context. 
engine.eval(code, isolatedContext); 
ScriptObjectMirror fn = (ScriptObjectMirror) isolatedContext 
     .getAttribute("main"); 

// Call it whenever 
fn.call("main", arg1, ar2, argEtc); 
+0

Я не понимаю, что такое ScriptObjectMirror. но я попробую ваш подход и дам вам знать спасибо – Zo72

+0

Это не работает. Если мой код «новый java.util.HashMap()», он позволяет мне его создать ... что полностью поражает мою цель – Zo72