0

问题: 我试图提供所有限制(黑名单),并且只允许我们使用GroovyClassLoader执行 groovy 时提供的内容

我只能使用GroovyClassLoader的有限权限来执行自定义策略。

现在我正在尝试提供包限制,以用作 groovy 执行的一部分。假设如果我允许com.xy这个包,如果有任何包,那么在 groovy 中使用的这个包应该抛出SecurityException

我试图通过自定义安全管理器实现相同的目标并覆盖checkPackageAccess但没有成功。

    public TestSecurityManager extends SecurityManager{

    List<String> whiteListedPkgList;

     public void checkPackageAccess(String pkg){
         if(!pkg.startWith(any of given white list pkg)){
           throw new SecurityException("Access Denied");
           }
        //If package not belong to whilelisted package list throw security exception
       }
    }

当我尝试使用上述方法时,我们需要提供所有用于执行的包,例如 com、java等,而不是java.nio.file。在白名单中

更新

如果我们尝试使用白名单比较来允许com.xy 之类的包,使用 start with check access pkg,它将允许该包,但稍后它将为com抛出安全异常。

任何人都可以帮助我们如何实现它吗?

提前致谢

4

1 回答 1

1

如果您能够使用 Groovy DSL 功能而不是使用 Java 的 SecurityManager,那么您可以更轻松地实现这一点。

请参阅https://www.groovy-lang.org/dsls.html#_secure_ast_customizer

例子:

import groovy.transform.CompileStatic
import org.codehaus.groovy.control.CompilerConfiguration
import org.codehaus.groovy.control.customizers.CompilationCustomizer
import org.codehaus.groovy.control.customizers.SecureASTCustomizer

@CompileStatic
class Main {
    static final CompilationCustomizer scz = new SecureASTCustomizer().with {
        closuresAllowed = false // user will not be able to write closures
        methodDefinitionAllowed = false // user will not be able to define methods
        importsWhitelist = [] // empty whitelist means imports are disallowed
        staticImportsWhitelist = [] // same for static imports
        staticStarImportsWhitelist = ['java.lang.Math'] // only java.lang.Math is allowed
        constantTypesClassesWhiteList = [
                Integer,
                Float,
                Long,
                Double,
                BigDecimal,
                Integer.TYPE,
                Long.TYPE,
                Float.TYPE,
                Double.TYPE,
                Object,
                String,
        ].asImmutable() as List<Class>
        // method calls are only allowed if the receiver is of one of those types
        // be careful, it's not a runtime type!
        receiversClassesWhiteList = [
                Math,
                Integer,
                Float,
                Double,
                Long,
                BigDecimal,
                PrintStream,
                Object,
        ].asImmutable() as List<Class>

        it
    }

    static void main(args) {
        def configuration = new CompilerConfiguration()
        configuration.addCompilationCustomizers(scz)

        // evaluate sandboxed code
        new GroovyShell(configuration).evaluate(
                """ println 'hello world' """)
    }

}

如果您只需要将某些类列入白名单,您还可以尝试编写自己的类加载器并使用它来评估沙盒脚本:

class MyClassLoader extends ClassLoader {

    Set<String> whiteListPackages = [
            'java.lang.', 'java.util.', 'groovy.', 'org.codehaus.groovy.', 'Script'
    ]

    MyClassLoader(ClassLoader parent) {
        super(parent)
    }

    @Override
    protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
        if (!whiteListPackages.any { okPkg -> name.startsWith(okPkg) }) {
            throw new ClassNotFoundException('Access is forbidden')
        }
        return super.loadClass(name, resolve)
    }
}

def shell = new GroovyShell(new MyClassLoader(GroovySystem.classLoader))

// evaluate the script with our own classloader
shell.evaluate('''
println 'hello'
println([1,2,3])

// This line throws an error because the `java.net` package is not whitelisted
println(new URL('https://groovy-lang.org'))
''')
于 2020-01-28T18:20:10.443 回答