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

如何在沙箱中使用Rhino for Java运行Javascript?,java,javascript,sandbox,rhino,Java,Javascript,Sandbox,Rhino,java应用程序的一部分需要运行非开发人员编写的javascript。这些非开发人员正在使用javascript进行数据格式化。(主要是简单的逻辑和字符串连接) 我的问题是如何设置这些脚本的执行,以确保脚本错误不会对应用程序的其余部分产生重大负面影响 需要防止无限循环 防止产生新线程 限制对服务和环境的访问 文件系统(例如:如果不满的脚本编写器决定删除文件) 数据库(与删除数据库记录相同) 基本上,我需要将javascript范围设置为只包含他们需要的内容,而不包含更多内容。javasc

java应用程序的一部分需要运行非开发人员编写的javascript。这些非开发人员正在使用javascript进行数据格式化。(主要是简单的逻辑和字符串连接)

我的问题是如何设置这些脚本的执行,以确保脚本错误不会对应用程序的其余部分产生重大负面影响

  • 需要防止无限循环
  • 防止产生新线程
  • 限制对服务和环境的访问
    • 文件系统(例如:如果不满的脚本编写器决定删除文件)
    • 数据库(与删除数据库记录相同)

基本上,我需要将javascript范围设置为只包含他们需要的内容,而不包含更多内容。

javascript是单线程的,无法访问文件系统,因此我认为您不必担心这些问题。我不确定是否有办法设置一个超时来防止无限循环,但您总是可以生成一个执行脚本的(Java)线程,然后在这么长的时间后杀死该线程。

要防止无限循环,您需要将它放在一个单独的进程中,以便可以杀死它

为了防止创建线程,您需要扩展SecurityManager(默认实现允许不受信任的代码访问非根线程组)

Java安全性确实允许您阻止对文件系统的访问

对于数据库限制,您可能可以使用标准的SQL用户安全性,但这是非常薄弱的。否则,您需要提供一个API来强制执行您的限制


编辑:我应该指出,JDK6附带的Rhino版本已经完成了安全工作,但不包括编译器。

为了防止无限循环,您可以在脚本运行时观察指令计数(这只适用于解释脚本,不适用于编译脚本)

这样可以防止脚本运行超过10秒:

 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();
     }
 }

要阻止Java类和方法访问,请查看


我刚刚浏览了这篇博客文章,它似乎对沙盒或多或少的任何东西(不仅仅是Rhino)都很有用:


如果您只寻找纯JavaScript函数,下面是一个基于JDK embedded Rhino库的解决方案,无需导入任何第三方库:

  • 通过ScriptEngineManager#getEngineFactories查找JavaScript脚本引擎工厂类名
  • 在新的类加载器中加载脚本引擎工厂类,其中JavaMembers或其他相关类将被忽略
  • 在加载的脚本引擎工厂上调用#getScriptEngine,在返回的脚本引擎上调用eval脚本
  • 若给定的脚本包含Java脚本,类加载器将尝试加载JavaMembers或其他类,并触发类NotFound异常。这样,恶意脚本将在不执行的情况下被忽略

    有关更多详细信息,请阅读ConfigJSParser.java和ConfigJSClassLoader.java文件:


    Rhino有一个可用的线程库(java.lang.Thread!),可以访问文件系统。您的意思是(使用Rhino的Javascript)for(沙箱中的java)还是(使用Rhino的Javascript for java))(沙箱中)?