当前位置: 首页 > 知识库问答 >
问题:

安全的Nashorn JS执行

吕向阳
2023-03-14

如何使用Java8 Nashorn安全地执行用户提供的JS代码?

该脚本为一些基于servlet的报告扩展了一些计算。该应用程序有许多不同的(不受信任的)用户。脚本应该只能访问JavaObject和定义的成员返回的那些。默认情况下,脚本可以使用Class.forName()(使用我提供的对象的. getClass())实例化任何类。有没有什么方法可以禁止访问任何我没有明确指定的java类?

共有3个答案

张岳
2023-03-14

我研究了允许用户在沙箱中编写简单脚本的html" target="_blank">方法,该沙箱允许用户访问我的应用程序提供的一些基本对象(与谷歌应用程序脚本的工作方式相同)。我的结论是,Rhino比Nashorn更容易/更好地记录这一点。你可以:

>

限制指令的数量,以避免endess-loops与观察InstructionCount:http://www-archive.mozilla.org/rhino/apidocs/org/mozilla/javascript/ContextFactory.html

但是,请注意,对于不受信任的用户,这是不够的,因为他们仍然可以(意外或故意)分配大量内存,导致JVM抛出OutOfMemoryError。对于这最后一点,我还没有找到一个安全的解决方案。

吕峰
2023-03-14

添加到1.8u40中,可以使用ClassFilter来限制引擎可以使用的类。

以下是Oracle文档中的一个示例:

import javax.script.ScriptEngine;
import jdk.nashorn.api.scripting.ClassFilter;
import jdk.nashorn.api.scripting.NashornScriptEngineFactory;
 
public class MyClassFilterTest {
 
  class MyCF implements ClassFilter {
    @Override
    public boolean exposeToScripts(String s) {
      if (s.compareTo("java.io.File") == 0) return false;
      return true;
    }
  }
 
  public void testClassFilter() {
 
    final String script =
      "print(java.lang.System.getProperty(\"java.home\"));" +
      "print(\"Create file variable\");" +
      "var File = Java.type(\"java.io.File\");";
 
    NashornScriptEngineFactory factory = new NashornScriptEngineFactory();
 
    ScriptEngine engine = factory.getScriptEngine(
      new MyClassFilterTest.MyCF());
    try {
      engine.eval(script);
    } catch (Exception e) {
      System.out.println("Exception caught: " + e.toString());
    }
  }
 
  public static void main(String[] args) {
    MyClassFilterTest myApp = new MyClassFilterTest();
    myApp.testClassFilter();
  }
}

此示例打印以下内容:

C:\Java\jre8
Create file variable
Exception caught: java.lang.RuntimeException: java.lang.ClassNotFoundException:
java.io.File
陈斌蔚
2023-03-14

不久前,我在Nashorn邮件列表上问了这个问题:

对于将Nashorn脚本可以创建的类限制为白名单的最佳方式,是否有任何建议?或者该方法与任何JSR223引擎(ScriptEngineManager构造函数上的自定义类加载器)相同?

从纳肖恩的一个开发者那里得到了这个答案:

你好

>

  • Nashorn已经过滤了类——只过滤非敏感包的公共类(在package.access安全属性aka'sensitive'中列出的包)。包访问检查是在无权限上下文中完成的。i、 例如,只允许从无权限类访问任何包。

    Nashorn过滤Java reflective和jsr292访问——除非脚本具有RuntimePermission(“Nashorn.JavaReflection”),否则脚本将无法进行反射。

    以上两项要求在启用SecurityManager的情况下运行。在没有安全管理器的情况下,上述过滤将不适用。

    您可以删除全局范围内的全局Java.type函数和Packages对象(com, edu, java, javafx, javax, org, JavaImaver)和/或用您实现的任何过滤函数替换它们。因为,这些是从脚本Java访问的唯一入口点,自定义这些函数=

    有一个未记录的选项(现在仅用于运行test262测试)"--no-java"的nashorn shell为您执行上述操作。即,Nashorn不会在全局范围内初始化Java钩子。

    JSR223不提供任何基于标准的钩子来传递自定义类加载器。这可能必须在jsr223的(可能的)未来更新中解决。

    希望这有帮助,

    -圣达

  •  类似资料:
    • 消费者是一个spring集成项目,它从消息队列中消费并执行大量处理。我使用Executor通道并行处理消息,然后流通过一些公共处理程序类。 请在下面的代码片段中找到- -我们从EMS队列接收消息并将其发送到路由器 -基于以下消息的id:“特定ExecutorChannel实例配置了一个单线程执行器。每个ExecutorChannel都将是它的专用执行器,只有一个线程。 -所有ExecutorCha

    • 我使用Spring Boot ()和Jersey (pom依赖项:< code > spring-boot-starter-Jersey ,< code > spring-boot-starter-actuator ,< code > spring-boot-starter-web ,< code > spring-boot-starter-security )。 我有一个泽西岛endpoint(

    • Spring Boot执行器endpoint默认受基本http安全保护。 这个可以改成使用Spring Security吗?我已经成功地设置了Spring Security并使用它来保护我的其他页面。 我尝试了并在授权请求中添加了(注意,我使用了不同的url作为endpoint的根用户),但这没有帮助。我一直得到一个基本的http身份验证日志,它不是用户在AuthenticationManager

    • 我正在使用Spring Boot安全性和Oauth2。我不想禁用健康endpoint的安全性。 我可以完全禁用安全性,或者编写自己的实现并禁用autoconfigured One。 但是如何修改()的现有实现? 我试图创建自己的配置而不禁用AutoConfigurated一个,但由于冲突,这是不可能的。 以下是错误消息: 此外,我试图显式地为我自己的安全配置设置更高的顺序,但看起来自动配置的一个覆