当从java执行groovy脚本时如何阻止对某些类的访问? [英] How to block access to some classes, when executing groovy scripts from java?

查看:261
本文介绍了当从java执行groovy脚本时如何阻止对某些类的访问?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对groovy和java中的脚本编程一般都很陌生,而且我真的非常喜欢
,希望对我的问题有一个简单的解决方案。
在我们的应用程序中,用户可以执行它们自己编写
的groovy脚本,并且我们需要控制这些脚本可以执行和不能执行的操作。
我阅读了很多关于沙盒常规的内容,但是无论我是在看
错误的地方,还是忽视这些显而易见的地方。
为了简单起见,我有一个小例子来说明问题。
这是我的类加载器,它应该阻止 java.lang.System
加载并可用于脚本:

  public class MyClassLoader extends ClassLoader {

@Override
public Class<?> loadClass(String name)抛出ClassNotFoundException {b $ b if(name.startsWith(java.lang.System)){
抛出新的ClassNotFoundException(Class not found:+ name);
}
返回super.loadClass(name);




$ b

这是一个简单的程序,它试图调用 System.currentTimeMillis()

  public static void main(String []] args){
String code =java.lang.System.currentTimeMillis();;
ClassLoader classLoader = new MyClassLoader();
Thread.currentThread()。setContextClassLoader(classLoader);

GroovyShell shell = new GroovyShell();
Script script = shell.parse(code);
Object result = script.run();
log.debug(result);
}

MyClassLoader 抛出异常对于 java.lang.SystemBeanInfo
java.lang.SystemCustomizer ,但代码执行。
如果使用 javax.script 类,则会发生同样的事情:

  ScriptEngineManager factory = new ScriptEngineManager(); 
ScriptEngine engine = factory.getEngineByName(Groovy);
Object o = engine.eval(code);
log.debug(o);

如果我使用JavaScript引擎进行尝试,它可以按预期工作(只需将
Groovy与上面的例子中的JavaScript)。

任何人都可以帮我解决这个问题吗?顺便说一句,我使用groovy-all-1.8.8.jar,用
jdk1.7.0_55。

谢谢

解决方案

我可以推荐 Groovy的沙盒为此目的。与 SecureASTCustomizer 相比,它会检查运行时是否允许执行动态。它拦截每一个方法调用,对象分配,属性/属性访问,数组访问等等 - 因此你对你允许的内容(白名单)有一个非常细致的控制。



当然,允许配置的配置非常重要。例如,你可能想要允许使用 String s并使用像 substring 这样的方法,但可能不是<$ c $对字符串执行方法,可以利用'rm -R〜/ *'。 ()
创建一个真正安全的配置是一项挑战,越容易越难。



Groovy Sandbox的不足之处在于代码必须在拦截器注册的情况下运行,你会在执行过程中有一个性能损失。



这张图片[ 1 ]显示了一个项目的例子,我们使用Groovy Sandbox来处理由用户输入的Groovy代码。代码被运行以消除脚本 - 所以如果那里的语句实际上会作为它的一部分被执行,那么应用程序会在我做屏幕截图之前退出;)


I'm pretty new to groovy, and scripting in java generally, and I really hope there is a simple solution for my problem. In our application, the users can execute groovy scripts which they write themselves, and we need to control what those scripts can and can not do. I read a lot of stuff about sandboxing groovy, but either I am looking at wrong places or I am overlooking the obvious. To make it simple, I have a small example which demonstrates the problem. This is my class loader which should prevent java.lang.System from being loaded and available to scripts:

public class MyClassLoader extends ClassLoader {

    @Override
    public Class<?> loadClass(String name) throws ClassNotFoundException {
        if (name.startsWith("java.lang.System")) {
            throw new ClassNotFoundException("Class not found: " + name);
        }
        return super.loadClass(name);
    }
}

And this is a simple program that tries to call System.currentTimeMillis():

public static void main(String[] args) {
    String code = "java.lang.System.currentTimeMillis();";
    ClassLoader classLoader = new MyClassLoader();
    Thread.currentThread().setContextClassLoader(classLoader);

    GroovyShell shell = new GroovyShell();
    Script script = shell.parse(code);
    Object result = script.run();
    log.debug(result);
}

MyClassLoader throws exceptions for java.lang.SystemBeanInfo and java.lang.SystemCustomizer, but the code executes. Same thing happens if I use javax.script classes:

ScriptEngineManager factory = new ScriptEngineManager();
ScriptEngine engine = factory.getEngineByName("Groovy");
Object o = engine.eval(code);
log.debug(o);

And if I try it with JavaScript engine, it works as expected (just replace "Groovy" with "JavaScript" in the above example).

Can anyone help me with this? BTW, I'm using groovy-all-1.8.8.jar, with jdk1.7.0_55.

Thanks

解决方案

I can recommend Groovy Sandbox for this purpose. In contrast to SecureASTCustomizer it will check if an execution is allowed dynamically at runtime. It intercepts every method call, object allocations, property/attribute access, array access, and so on - and you thus have a very fine grained control on what you allow (white-listing).

Naturally the configuration on what is allowed is very important. For example you may want to allow using Strings and use methods like substring, but probably not the execute method on String, which could be exploited with something like 'rm -R ~/*'.execute(). Creating a configuration that is really safe is a challenge, and it is more difficult the more you allow.

Downside of the Groovy Sandbox is that the code must run with the interceptor registered and you will have a performance penalty during execution.

This image [1] shows an example from a project where we used Groovy Sandbox for Groovy code entered by the user. The code is run to valide the script - so if the statement there would actually be executed as part of it, the application would have exited before I could do the screenshot ;)

这篇关于当从java执行groovy脚本时如何阻止对某些类的访问?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆