栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

如何创建安全的JEXL(脚本)沙箱?

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

如何创建安全的JEXL(脚本)沙箱?

更新:这一切都使用JEXL 2.0.1完成。 您可能需要对此进行调整以使其与较新的版本一起使用。

这是我处理每种情况的方法。我已经创建了单元测试来测试每种情况,并且已经验证它们可以工作。

  1. JEXL使这个过程非常容易。只需创建一个自定义的ClassLoader。重写两个loadClass()方法。在JexlEngine上,调用setClassLoader()。

  2. 同样,JEXL使这变得非常容易。您必须同时阻止“ .class”和“ .getClass()”。创建您自己的扩展UberspectImpl的Uberspect类。覆盖getPropertyGet,如果标识符等于“ class”,则返回null。重写getMethod,如果方法等于“ getClass”,则返回null。构造JexlEngine时,请传递对您的Uberspect实现的引用。

    class MyUberspectImpl extends UberspectImpl {public MyUberspectImpl(Log jexlLog) {    super(jexlLog);}@Overridepublic JexlPropertyGet getPropertyGet(Object obj, Object identifier, JexlInfo info) {    // for security we do not allow access to .class property    if ("class".equals(identifier)) throw new RuntimeException("Access to getClass() method is not allowed");    JexlPropertyGet propertyGet = super.getPropertyGet(obj, identifier, info);    return propertyGet;}@Overridepublic JexlMethod getMethod(Object obj, String method, Object[] args, JexlInfo info) {    // for security we do not allow access to .getClass() method    if ("getClass".equals(method)) throw new RuntimeException("Access to getClass() method is not allowed");    return super.getMethod(obj, method, args, info);}

    }

  3. 您可以使用Java的AccessController机制来执行此操作。我将对此进行快速介绍。使用-Djava.security.policy = policyfile启动Java。创建一个名为policyfile的文件,其中包含以下行:grant {权限java.security.AllPermission; }; 通过以下调用设置默认的SecurityManager:System.setSecurityManager(new SecurityManager()); 现在,您可以控制权限,并且您的应用默认具有所有权限。当然,最好将应用程序的权限限制为仅需要它的权限。接下来,创建一个将访问权限限制到最低限度的AccessControlContext,并调用AccessController.doPrivileged()并传递AccessControlContext,然后在doPrivileged()中执行JEXL脚本。这是一个演示此操作的小程序。JEXL脚本调用System.exit(1),如果不是,

    System.out.println("java.security.policy=" + System.getProperty("java.security.policy"));

    System.setSecurityManager(new SecurityManager());
    try {
    Permissions perms = new Permissions();
    perms.add(new RuntimePermission(“accessDeclaredMembers”));
    ProtectionDomain domain = new ProtectionDomain(new CodeSource( null, (Certificate[]) null ), perms );
    AccessControlContext restrictedAccessControlContext = new AccessControlContext(new ProtectionDomain[] { domain } );


    JexlEngine jexlEngine = new JexlEngine();final script finalexpression = jexlEngine.createscript(        "i = 0; intClazz = i.class; "        + "clazz = intClazz.forName("java.lang.System"); "        + "m = clazz.methods; m[0].invoke(null, 1); c");AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {    @Override    public Object run() throws Exception {        return finalexpression.execute(new MapContext());    }}, restrictedAccessControlContext);

    }
    catch (Throwable ex) {
    ex.printStackTrace();
    }

  4. 技巧是在脚本完成之前中断脚本。我发现做到这一点的一种方法是创建一个自定义JexlArithmetic类。然后重写该类中的每个方法,并在调用超类中的real方法之前检查脚本是否应停止执行。我正在使用ExecutorService创建线程。调用Future.get()时,要经过等待时间。如果抛出TimeoutException,则调用Future.cancel(),这会中断运行脚本的线程。在新的JexlArithmetic类的每个重写的方法内部,检查Thread.interrupted(),如果为true,则抛出java.util.concurrent.CancellationException。是否有更好的位置放置将在执行脚本时定期执行的代码,以便可以将其中断?

这是MyJexlArithmetic类的节选。您必须添加所有其他方法:

    public class MyJexlArithmetic extends JexlArithmetic {        public MyJexlArithmetic(boolean lenient) { super(lenient);        }        private void checkInterrupted() { if (Thread.interrupted()) throw new CancellationException();        }        @Override        public boolean equals(Object left, Object right) { checkInterrupted(); return super.equals(left, right); //To change body of generated methods, choose Tools | Templates.        }        @Override        public Object add(Object left, Object right) { checkInterrupted(); return super.add(left, right);        }    }

这是我实例化JexlEngine的方法:

        Log jexlLog = LogFactory.getLog("JEXL");        Map <String, Object> functions = new HashMap();        jexlEngine = new JexlEngine(new MyUberspectImpl(jexlLog), new MyJexlArithmetic(false), functions, jexlLog);


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/570705.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号