简体   繁体   English

如何在沙盒中使用Rhino for Java运行Javascript?

[英]How can you run Javascript using Rhino for Java in a sandbox?

Part of our java application needs to run javascript that is written by non-developers. 我们的Java应用程序的一部分需要运行由非开发人员编写的javascript。 These non-developers are using javascript for data formatting. 这些非开发人员使用javascript进行数据格式化。 (Simple logic and string concatenation mostly). (主要是简单的逻辑和字符串连接)。

My question is how can I setup the execution of these scripts to make sure scripting errors don't have a major negative impact on the rest of the application. 我的问题是如何设置这些脚本的执行以确保脚本错误不会对应用程序的其余部分产生重大负面影响。

  • Need to guard against infinite loops 需要防范无限循环
  • Guard against spawning new threads. 防止产生新线程。
  • Limit access to services and environment 限制对服务和环境的访问
    • File system (Example: If a disgruntled script writer decided to delete files) 文件系统(示例:如果心怀不满的脚本编写者决定删除文件)
    • Database (Same thing delete database records) 数据库(同样删除数据库记录)

Basically I need to setup the javascript scope to only include exactly what they need and no more. 基本上我需要设置javascript范围,只包括他们需要的内容,而不是更多内容。

To guard against infinite loops, you can observe the instruction count as the script runs (this works only with interpreted scripts, not with compiled ones). 为了防止无限循环,您可以在脚本运行时观察指令计数(这仅适用于已解释的脚本,而不适用于已编译的脚本)。

There is this example in the Rhino JavaDocs to prevent a script from running for more than ten seconds: Rhino JavaDocs中有一个例子可以防止脚本运行超过十秒:

 protected void observeInstructionCount(Context cx, int instructionCount)
 {
     MyContext mcx = (MyContext)cx;
     long currentTime = System.currentTimeMillis();
     if (currentTime - mcx.startTime > 10*1000) {
         // More then 10 seconds from Context creation time:
         // it is time to stop the script.
         // Throw Error instance to ensure that script will never
         // get control back through catch or finally.
         throw new Error();
     }
 }

To block Java class and method access have a look at... 要阻止Java类和方法访问,请看...

http://codeutopia.net/blog/2009/01/02/sandboxing-rhino-in-java/ http://codeutopia.net/blog/2009/01/02/sandboxing-rhino-in-java/

To guard against infinite loops, you'd need to put it in a separate process so that it could be killed. 为了防止无限循环,你需要将它放在一个单独的进程中,以便它可以被杀死。

To guard against creating threads, you'd need to extend SecurityManager (the default implementation allows untrusted code to access non-root thread groups). 为了防止创建线程,您需要扩展SecurityManager(默认实现允许不受信任的代码访问非根线程组)。

Java security does allow you to prevent access to the file system. Java安全性允许您阻止对文件系统的访问。

For database restrictions, you might be able to use the standard SQL user security, but that is quite weak. 对于数据库限制,您可能能够使用标准SQL用户安全性,但这非常弱。 Otherwise, you need to provide an API that enforces your restrictions. 否则,您需要提供一个强制执行限制的API。

Edit: I should point out that the version of Rhino provided with JDK6 has had security work done on it, but doesn't include the compiler. 编辑:我应该指出,JDK6提供的Rhino版本已经完成了安全工作,但不包括编译器。

I just ran across this blog post that seems to be useful for sandboxing more or less anything (not just Rhino): 我刚刚浏览了这个博客帖子,似乎对沙箱或多或少的任何东西都有用(不仅仅是Rhino):

http://calumleslie.blogspot.com/2008/06/simple-jvm-sandboxing.html http://calumleslie.blogspot.com/2008/06/simple-jvm-sandboxing.html

If you are looking for pure JavaScript functions only, here is a solution basing on JDK embedded Rhino library without importing any 3rd-parties libraries: 如果您只是在寻找纯JavaScript函数,这里是一个基于JDK嵌入式Rhino库的解决方案,无需导入任何第三方库:

  1. Find out JavaScript script engine factory class name by ScriptEngineManager#getEngineFactories 通过ScriptEngineManager#getEngineFactories找出JavaScript脚本引擎工厂类名
  2. Load script engine factory class in a new class loader, in which JavaMembers or other related classes will be ignored. 在新的类加载器中加载脚本引擎工厂类,其中将忽略JavaMembers或其他相关类。
  3. Call #getScriptEngine on loaded script engine factory and eval scripts on returned script engine. 在已加载的脚本引擎工厂上调用#getScriptEngine,在返回的脚本引擎上调用eval脚本。

If given script contains Java script, class loader will try to load JavaMembers or other classes and trigger class not found exceptions. 如果给定脚本包含Java脚本,则类加载器将尝试加载JavaMembers或其他类并触发类未找到的异常。 In this way, malicious scripts will be ignored without execution. 这样,恶意脚本将被忽略而不执行。

Please read ConfigJSParser.java and ConfigJSClassLoader.java files for more details: 有关更多详细信息,请阅读ConfigJSParser.java和ConfigJSClassLoader.java文件:

https://github.com/webuzz/simpleconfig/tree/master/src/im/webuzz/config https://github.com/webuzz/simpleconfig/tree/master/src/im/webuzz/config

Javascript is single-threaded and can't access the filesystem, so I don't think you have to worry about those. Javascript是单线程的,无法访问文件系统,所以我认为你不必担心这些。 I'm not sure if there's a way to set a timeout to guard against infinite loops, but you could always spawn a (Java) thread that executes the script, and then kill the thread after so much time. 我不确定是否有办法设置超时以防止无限循环,但你总是可以生成一个执行脚本的(Java)线程,然后在这么多时间后终止线程。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM