我正在应用程序服务器Drools
中运行应用WildFly 10.1.0-Final
程序。由于执行的代码Drools
不受信任,我决定构建一个自定义沙箱以允许安全执行。
由于不能将外部模块添加到应用程序服务器,我决定,为了有效地使用这个沙箱,我必须创建一个合适的环境。
因此,在standalone.xml
服务器中,我为所有战争定义了 amaximum-set
和 aminimum-set
的权限,我将其设置为java.permission.AllPermission
,从而通常允许执行所有代码。
然后我将-secmgr
标志添加到服务器,以激活 SecurityManager。我能够按预期使用该应用程序,并且多次调用AccessController.doPrivileged()
确实检查了权限并允许执行所需的操作。
然后我创建了一个服务类,它将创建一个沙盒上下文来检查访问。
它显式地创建了一个AccessControlContext
带有 a CodeBase
of null
(意思是所有代码)和 aProtectionDomain
带有三个必要的 Drools 权限-Runtime.getClassLoader
和. 然后,我使用所需的调用 ( ) 和沙盒上下文进行调用。Runtime.accessDeclaredMembers
Reflect.suppressAccessChecks
AccessController.doPrivileged
StatefulKnowledgeSession.fireAllRules
在我的开发系统上,当一个 drools 规则尝试做任何不允许的事情(例如,创建一个文件)时,aConsequenceException
会抛出一个AccessControlException
原因,因为 do denied Access to File.write
.
在我们的生产系统上,使用了相同的配置和部署,但所有调用都由于不允许的AccessControlException
状态而失败。Runtime.getClassLoader
我调试了实时系统,调用sandboxContext.checkPermission(new RuntimePermission("getClassLoader"))
时没有抛出异常,这告诉我上下文本身允许它。
尽管如此,我们的生产机器拒绝许可
系统中唯一的区别是操作系统版本,因为我使用的是一台Ubuntu
机器,而生产服务器是一CentOS
台机器。
更新
调试服务器发现,还有另一个ProtectionDomain
未签名且没有代码库,并且缺少Runtime.getClassLoader
权限。但是,ProtectionDomain
我的开发机器上不存在该特定内容,并且我无法找到该特定内容的来源。
更新 2
更多信息:当抛出异常时,AccessControlStack 包含一个特权上下文(我实例化和预期的那个)和 5 个额外ProtectionDomain
的 s。如前所述,其中一个(有问题的)有 a CodeSource
of (null <no signer certificates>)
,没有 Principals,有 anull
PermissionCollection
并且使用org.drools.util.CompositeClassLoader
.
此域授予的权限(取自domain.toString()
):
("java.net.SocketPermission" "localhost:0" "listen,resolve")
("java.net.SocketPermission" "localhost:0" "listen,resolve")
("javax.security.jacc.WebResourcePermission" "/")
("java.util.PropertyPermission" "java.specification.version" "read")
("java.util.PropertyPermission" "java.version" "read")
("java.util.PropertyPermission" "os.arch" "read")
("java.util.PropertyPermission" "java.specification.vendor" "read")
("java.util.PropertyPermission" "java.vm.specification.name" "read")
("java.util.PropertyPermission" "java.vm.vendor" "read")
("java.util.PropertyPermission" "path.separator" "read")
("java.util.PropertyPermission" "os.version" "read")
("java.util.PropertyPermission" "file.separator" "read")
("java.util.PropertyPermission" "line.separator" "read")
("java.util.PropertyPermission" "java.vm.specification.vendor" "read")
("java.util.PropertyPermission" "java.specification.name" "read")
("java.util.PropertyPermission" "java.vendor.url" "read")
("java.util.PropertyPermission" "java.vendor" "read")
("java.util.PropertyPermission" "java.vm.version" "read")
("java.util.PropertyPermission" "java.vm.name" "read")
("java.util.PropertyPermission" "java.vm.specification.version" "read")
("java.util.PropertyPermission" "os.name" "read")
("java.util.PropertyPermission" "java.class.version" "read")
("java.lang.RuntimePermission" "stopThread")
("javax.security.jacc.WebRoleRefPermission" "" "**")
("javax.security.jacc.WebRoleRefPermission" "Faces Servlet" "**")
("javax.security.jacc.WebRoleRefPermission" "metaform" "**")
("javax.security.jacc.WebUserDataPermission" "/")
Runtime.getClassLoader
但是,根据我阅读的文档,这显然没有,因为我通过 授予该权限doPrivileged
,这根本不重要。
我看到 ApplicationServer 使用 Wildfly-Elytron 1.0.2.Final 作为其 SecurityManager - Elytron 是否有可能不实现此行为?
更新 3:
第三台开发机器被用来检查,那台机器也失败了。由于这台机器也使用 Ubuntu,我们可以肯定地说这不是CentOS
原因。
更新 4:
如您所见,授予的权限与默认java.policy
权限大致相同,根据 Wildfly Docs 的说法,甚至不应再使用默认权限。
我们发现org.jboss.security.jacc.DelegatingPolicy
似乎委托给了中定义的权限,java.policy
而不是standalone.xml
.