11

我想创建一个安全的 ColdFusion 环境,为此我使用了多个沙箱配置。使用友好的管理员界面可以轻松完成以下任务:

  • 限制 CFtags,例如: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.Runtime&java.lang.ProcessBuilder用于createObject(). 注意:我也尝试过 sanbox 和 os 权限中的文件限制,但不幸的是,它们似乎只适用于 I/O 文件操作,我不能弄乱系统库的安全策略,因为它们可能在内部使用由冷融合。

4

1 回答 1

6

根据@Leigh和@ Miguel-F的有用建议,我尝试实施Security Managerand Policy。结果如下:

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

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

里面有一个不错的 GUI 实用程序,jre\bin\policytool.exe允许您轻松有效地管理策略条目。

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 参数中定义它。

//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";

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

//perform the check
try{
  sm.checkExec("notepad.exe");
}
catch(SecurityException e){
  //do something...show warning.
}
于 2015-06-16T11:23:46.983 回答