我试图防止在主Java应用程序“内部”运行的插件访问它们不应访问的内容。我已经阅读了有关Policy,AccessControllers和ProtectionDomains的内容,但是它们非常面向JAR。

我已经试过了:

import java.nio.file.Files
import java.nio.file.Paths
import java.security.*


fun main(args: Array<String>) {
    Policy.setPolicy(object : Policy() {})
    System.setSecurityManager(SecurityManager())

    val domain = ProtectionDomain(null, Permissions() /* no permissions */)
    AccessController.doPrivileged(PrivilegedAction {
        untrusted()
    }, AccessControlContext(arrayOf(domain)))
}

fun untrusted() {
    try {
        // Works as expected
        Files.readAllBytes(Paths.get("build.gradle"))
        throw IllegalStateException("Was able to access file, but shouldn't have been able to")
    } catch (e: AccessControlException) {
    }
    try {
        // Should throw AccessControlException, but doesn't
        AccessController.doPrivileged(PrivilegedAction {
            Files.readAllBytes(Paths.get("build.gradle"))
        })
        throw IllegalStateException("Was able to access file, but shouldn't have been able to")
    } catch (e: AccessControlException) {
    }
}


即使我通过自定义的限制untrusted()调用ProtectionDomain,似乎也可以轻易摆脱它。我期望doPrivileged中的untrusted调用可以与最外面的ProtectionDomain(具有所有权限的主程序)和调用方的ProtectionDomain(没有权限)的权限相交,导致untrusted基本上具有0个权限。



我也尝试过这样的域集:

val domain = ProtectionDomain(CodeSource(URL("http://foo"), null as Array<CodeSigner>?), Permissions() /* no permissions */)


但这也行不通-使用主程序的Policy而不是调用ProtectionDomain的那个来查询untrusted()。 (显然,我需要更新Policy以正确处理“ http://foo”,但无论如何它甚至都不会检查ProtectionDomain



那么我的理解哪里出错了?

最佳答案

在对此进行了一些研究之后,我想我有了答案。我可以写更长的答案,但我想我只是顺其自然。

由ClassLoader加载的每个类都有一个与之关联的ProtectionDomain + CodeSource。这些有点粗糙-CodeSource表示类的来源,但它不是指向单个.class文件或任何内容的指针-而是指向目录或JAR。因此,同一JAR或目录中的两个类通常具有相同的权限。任何具有可识别ProtectionDomain + CodeSource的类或脚本都可以通过您的策略列入白名单/黑名单。

当然,例外情况(kinda)是带有许可参数的AccessController.doPrivileged。这使您可以限制代码区域的权限。但是从理论上讲,该代码可以仅使用回调来调用AccessController.doPrivileged。该方法签名意味着“不要检查我的整个调用堆栈的权限;只需在策略文件中查找我的ProtectionDomain + CodeSource并查看其内容即可。”因此,如果您运行的是真正不受信任的代码,则最好确保做到这一点。它具有与您信任的应用程序不同的ProtectionDomain + CodeSource,并且b。您的策略能够识别该代码并授予其适当限制的权限。

08-17 02:59