使用AccessController.doPrivileged()的限制权限并不总是按预期方式工作

问题描述 投票:0回答:1

我设法用下面的代码建立了一个“ Java沙箱”:

    // #1
    new File("xxx").exists();

    // #2
    PrivilegedExceptionAction<Boolean> untrusted = () -> new File("xxx").exists();
    untrusted.run();

    // #3
    Policy.setPolicy(new Policy() {
        @Override public boolean implies(ProtectionDomain domain, Permission permission) { return true; }
    });
    System.setSecurityManager(new SecurityManager());

    AccessControlContext noPermissionsAccessControlContext;
    {
        Permissions noPermissions = new Permissions();
        noPermissions.setReadOnly();

        noPermissionsAccessControlContext = new AccessControlContext(
            new ProtectionDomain[] { new ProtectionDomain(null, noPermissions) }
        );
    }

    AccessControlContext allPermissionsAccessControlContext;
    {
        Permissions allPermissions = new Permissions();
        allPermissions.add(new AllPermission());
        allPermissions.setReadOnly();

        allPermissionsAccessControlContext = new AccessControlContext(
            new ProtectionDomain[] { new ProtectionDomain(null, allPermissions) }
        );
    }

    // #4
    try {
        AccessController.doPrivileged(untrusted, noPermissionsAccessControlContext);
        throw new AssertionError("AccessControlException expected");
    } catch (AccessControlException ace) {
        ;
    }

    // #5
    PrivilegedExceptionAction<Boolean> evil = () -> {
        return AccessController.doPrivileged(untrusted, allPermissionsAccessControlContext);
    };
    try {
        AccessController.doPrivileged(evil, noPermissionsAccessControlContext);
        throw new AssertionError("AccessControlException expected"); // Line #69
    } catch (AccessControlException ace) {
        ;
    }

#1#2应该不言自明。

#3是设置沙箱的代码:它设置了一个完全不受限制的Policy(否则我们将立即锁定自己),然后设置一个系统SecurityManager

#4然后在完全受限的AccessControlContext中执行“不受信任”的代码,这将导致我想要的AccessControlException。很好。

现在是#5,其中一些邪恶的代码试图从沙箱中“逃脱”:它创建了另一个完全不受限制的AccessControlContext,并在其中运行不受信任的代码。我希望这也会抛出AccessControlException,因为邪恶的代码成功地离开了沙箱,但事实并非如此:

Exception in thread "main" java.lang.AssertionError: AccessControlException expected
at sbtest.Demo.main(Demo.java:69)

根据我在JRE JAVADOC中阅读的内容

doPrivileged
public static <T> T doPrivileged(PrivilegedExceptionAction<T> action, AccessControlContext context)
     throws PrivilegedActionException

Performs the specified PrivilegedExceptionAction with privileges enabled and restricted by the
specified AccessControlContext. The action is performed with the intersection of the the permissions
possessed by the caller's protection domain, and those possessed by the domains represented by the
specified AccessControlContext.

If the action's run method throws an unchecked exception, it will propagate through this method.

Parameters:
    action -  the action to be performed
    context - an access control context representing the restriction to be applied to the caller's
              domain's privileges before performing the specified action. If the context is null,
              then no additional restriction is applied.
Returns:
    the value returned by the action's run method
Throws:
    PrivilegedActionException - if the specified action's run method threw a checked exception
    NullPointerException      - if the action is null
See Also:
    doPrivileged(PrivilegedAction), doPrivileged(PrivilegedExceptionAction,AccessControlContext)

,我希望不受信任的代码将使用no权限执行,并因此抛出AccessControlException,但不会发生。

为什么?我该怎么办才能修复该安全漏洞?

java permissions sandbox securitymanager accesscontrolexception
1个回答
0
投票

嗯,不受信任的代码最初确实会在没有权限的情况下执行...直到它请求恢复其权限(使用doPrivileged AllPermission嵌套AccessControlContext调用)。该请求得到了兑现,因为根据您的Policy,您的所有代码(包括“邪恶”操作)均具有完全特权。否则,doPrivileged不是“按需沙箱工具”。它仅用作其immediate

© www.soinside.com 2019 - 2024. All rights reserved.