如何限制在特定的Java类或包上使用createObject()方法?

11

我希望创建一个安全的ColdFusion环境,为此我正在使用多个沙盒配置。以下任务可通过友好的管理员界面轻松实现:

  • 限制CF标签如:cfexecute、cfregistry和cfhttp。
  • 禁用对内部ColdFusion Java组件的访问。
  • 仅允许第三方资源访问某些服务器和端口范围。

其它任务需要相应地配置web服务器。

问题:

然而,我很满意这个设置,但后来发现,尽管对cfexecute标签施加了限制,但可以使用java.lang.Runtime轻松执行系统文件或脚本;

String[] cmd = {"cmd.exe", 'net stop "ColdFusion 10 Application Server"'};
Process p = Runtime.getRuntime().exec(cmd);

或者使用 java.lang.ProcessBuilder

ProcessBuilder pb = new ProcessBuilder("cmd.exe", 'net stop "ColdFusion 10 Application Server"');
....
Process myProcess = pb.start();
问题是我无法找到任何解决方案来禁用这两个类:java.lang.Runtimejava.lang.ProcessBuilder,以供createObject()使用。 顺便提一下:我已经尝试了沙箱中的文件限制和操作系统权限,但不幸的是它们似乎只适用于I/O文件操作,而我不能搞乱系统库的安全策略,因为它们可能会被ColdFusion在内部使用。

1
你能否通过GUI禁用CreateObject(Java)函数,还是这样会太过限制?关于设置下的管理员设置禁用访问内部ColdFusion Java组件呢?你有检查过吗? - Miguel-F
禁用CreateObject(Java)是我在事后的第一个想法,但是还有CfObject可以实现相同的功能。而完全限制这两个功能确实太过严格,因为它们在整个应用程序中都被使用。如果有一种方法只禁用这两种情况中的type=java,那么问题就会得到解决。我有一种感觉,可能有一些JVM参数可以允许这种限制。 - Anurag
1
我找到了一篇类似的文章。其中他们谈论共享托管环境中的安全性,但提到的问题与您发现的问题相同。不幸的是,他们也没有给出解决方案。因此,主机商只能面临一个艰难的选择:禁用CFEXECUTE、CFOBJECT、CreateObject(.NET)、CreateObject(COM)和CreateObject(JAVA),或者接受在共享托管配置中根本没有安全性这一事实。- http://jochem.vandieten.net/2008/12/09/cf-shared-hosting-security-java-cfexecute-com-net-and-java-again/ - Miguel-F
1
从我所读的内容来看,通常您会实现一种类似于 SecurityManager 的东西。(可能甚至是CF实现沙盒功能的方式)。然而,我不知道安全策略对CF代码的其他部分会产生什么影响,如果有的话。 - Leigh
2
仅作澄清,当启用沙箱安全性时,ColdFusion确实使用Security Manager。从文档中得知:要在J2EE版本中使用沙箱安全,请确保应用程序服务器正在运行安全管理器(java.lang.SecurityManager),并且您定义以下JVM参数(对于Tomcat来说,这是cf_root/cfusion/bin/jvm.config文件中的java.args行)- -Djava.security.manager "-Djava.security.policy=cf_root/WEB-INF/cfusion/lib/coldfusion.policy" "-Djava.security.auth.policy=cf_root/WEB-INF/cfusion/lib/neo_jaas.policy" - Miguel-F
显示剩余8条评论
1个回答

6

在@Leigh和@Miguel-F提供的有用建议下,我尝试实现了Security ManagerPolicy。以下是结果:

1. 在运行时指定一个附加策略文件,而不是更改默认的java.policy文件。为此,我们需要使用CFAdmin界面添加以下参数到JVM参数中,或者将其追加到jvm.config文件中的jvm.args行中:

-Djava.security.manager -Djava.security.policy="c:/policies/myRuntime.policy"

jre\bin\内置了一个名为policytool.exe的很棒的GUI实用程序,可以轻松高效地管理策略条目。

2. 我们已经强制执行了安全管理器,并提供了自定义安全策略文件,其中包含:

    grant codeBase "file:///D:/proj/secTestProj/main/-"{
        permission java.io.FilePermission 
        "<<ALL FILES>>", "read, write, delete";
    };

在这里,我们将所有文件的FilePermission设置为read,write,delete,从列表中排除execute,因为我们不希望使用java运行时执行任何类型的文件。
注意:如果我们想要策略适用于所有应用程序而不考虑源,则可以将代码库设置为空字符串。
我真的希望在策略文件中有一个deny规则,类似于我们正在使用的grant规则,但很遗憾没有。如果您需要制定一组复杂的安全策略,可以使用Prograde库,该库实现了具有拒绝规则的策略文件(stack ref.)。 您可以将<<ALL FILES>>替换为单个文件,并相应地设置权限,或者为更好的控制使用<<ALL FILES>>和单个文件权限的组合。
参考文献:默认策略实施和策略文件语法JDK中的权限控制应用程序 这种方法解决了我们的核心问题:通过指定文件上允许的权限来拒绝使用java运行时执行文件。在另一种方法中,我们可以直接在应用程序中实现Security Manager来定义策略文件,而不是在JVM args中定义它。
//set the policy file as the system securuty policy
System.setProperty("java.security.policy", "file:/C:/java.policy");
// create a security manager
SecurityManager sm = new SecurityManager();
//alternatively, get the current securiy manager using System.getSecuriyManager() 
//set the system security manager
System.setSecurityManager(sm);

为了能够设置它,我们需要在策略文件中拥有这些权限:
permission java.lang.RuntimePermission "setSecurityManager";
permission java.lang.RuntimePermission "createSecurityManager";
permission java.lang.RuntimePermission "usePolicy";

在应用程序中使用安全管理器(Security Manager)对象具有其自身的优点,因为它公开了许多有用的方法。例如:CheckExec(String cmd)可检查调用线程是否允许创建子进程。

//perform the check
try{
  sm.checkExec("notepad.exe");
}
catch(SecurityException e){
  //do something...show warning.
}

非常棒的信息。感谢您发布它。我期待着尝试它 :) - Leigh
我仍然认为有一种更好的方法来实现我们在这里打算使用“Security Manager”和策略文件所要达到的目的。由于java.lang.RuntimePermission中没有任何目标名称可用于实现此目标(我最初期望在此处找到),因此我绕过了使用java.io.FilePermission。另一个优雅的解决方案是使用自定义“ClassLoaders”来过滤出最初关注的两个类:java.lang.Runtimejava.lang.ProcessBuilder - Anurag
我同意,即使自定义类加载器是一个解决方案,它们也不像策略机制那样适用普遍,因此我也没有任何经验,这是保持这个问题开放的另一个原因。最近我找到了一篇关于Java安全性的好文章。而对于Java应用程序中的沙箱技术和访问控制器(Access Controller),我在这个回答中思考是否存在另一种替代方案,即使这种方案可能不如策略机制好和干净。 - Anurag
我将会标记唯一的答案为被接受的答案,但愿赏金点数能在宽限期之前被领取。 - Anurag
虽然我很乐意被证明是错误的,但我真的认为自定义类加载器的方法对于CF应用程序来说并不可行。我无法找到任何一种干净的方式来强制执行它... - Leigh
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接