首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >安全地重用沙盒Nashorn容器

安全地重用沙盒Nashorn容器
EN

Stack Overflow用户
提问于 2016-11-27 19:30:38
回答 1查看 369关注 0票数 0

我正在实现一个沙盒JS环境,它允许用户上传他们的JS代码,并基于一组规则触发它。

我在Nashorn环境中禁用了Java访问,只允许访问一些实用类来执行一些操作,如HTTP请求、base64编码等。

目前,我为用户上传的每个JS代码创建ScriptEngine (Nashorn环境),但在我们的环境中,我们有许多预定义的JS代码,大多数用户都在使用它们。由于创建ScriptEngine的开销很大,我想对相同的JS代码块重用ScriptEngine。假设用户上传了以下代码:

代码语言:javascript
运行
复制
var main = function(event, userContext) {
   return event.get('time') + userContext.api_key;
}

userContext的工作原理类似于环境变量,用户在上传代码时设置上下文变量,我们将它们传递给main函数。由于JS代码除了main之外没有任何其他变量,因此它是无状态的,因此重用容器很容易。然而,对于下面的代码块,重用容器并不是一件容易的事情:

代码语言:javascript
运行
复制
var test = [];
var main = function(event, userContext) {
   test.push(1);
   return event.get('time') + userContext.api_key;
}

我正在寻找一种方法来抽象每个用户的本地变量,并重用具有不同本地上下文的环境,以便Java将JS代码编译为Java字节码,然后重用相同的字节码并在不同的上下文中调用它,就像类和对象之间的关系一样。

一种方法是为每个用户创建一个ENGINE_SCOPE,并在调用main函数时更改绑定。然而,我找不到克隆ScriptObjectMirror的方法。我的计划是在用户上传预编译的JS代码时创建新的作用域,并在调用函数时使用它。然而,Nashorn似乎不允许以编程方式创建引擎作用域。

另一个问题是JS允许修改全局对象。用户可以执行以下代码块而不会出现任何问题,所有执行的Object都将为null

代码语言:javascript
运行
复制
var test = [];
var main = function(event, userContext) {
   Object = null;
   return event.get('time') + userContext.api_key;
}

因此,我还需要禁止修改GLOBAL_SCOPE中的变量,但我找不到这样做的方法。

我知道重用容器可能还有其他安全问题,安全的方法是为用户上传的每个JS代码创建不同的容器。然而,与V8相比,创建Nashorn环境的成本非常高,而且如果运行时有太多的Nashorn环境,Java会填满Code Cache,因为它会尝试将JS代码块编译为Java字节码。我也对解决这个问题的其他建议持开放态度。

EN

回答 1

Stack Overflow用户

发布于 2017-01-23 07:02:32

我相信ScriptContext对象会隔离每一次执行。

代码语言:javascript
运行
复制
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
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40828426

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档