如何在某些 java 类 或包上限制 createObject()?

How to restrict createObject() on certain java classes or packages?

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

其他人相应地使用 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();

问题是我找不到任何允许我禁用这两个 类 的解决方案:createObject()java.lang.Runtimejava.lang.ProcessBuilder。 注意:我也尝试过 sanbox 中的文件限制和 os 权限,但不幸的是,它们似乎只适用于 I/O 文件操作,我不能弄乱系统库的安全策略因为它们可能会被 ColdFusion 内部使用。

根据@Leigh and @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,因为我们不希望使用 [=63= 执行任何类型的文件] 运行时。

注意:如果我们希望将策略应用于所有应用程序而不考虑来源,则可以将代码库设置为空字符串。

我真的希望在策略文件中有一个 deny 规则来使事情变得更容易,类似于我们正在使用的 grant 规则,但不幸的是没有。如果您需要实施一组复杂的安全策略,可以使用 Prograde library, which implements policy file with deny rule (stack ref.)。 您当然可以用单个文件替换 <<ALL FILES>> 并相应地设置权限,或者为了更好地控制使用 <<ALL FILES>> 和单个文件权限的组合。

参考文献:Default Policy Implementation and Policy File Syntax, Permissions in JDK and Controlling Applications

这种方法解决了我们的核心问题:通过指定文件允许的权限来拒绝使用 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.
}