如何在某些 java 类 或包上限制 createObject()?
How to restrict createObject() on certain java classes or packages?
我想创建一个安全的 ColdFusion 环境,为此我使用了多个沙箱配置。使用友好的管理员界面可以轻松完成以下任务:
- 限制 CFtag,例如: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();
问题是我找不到任何允许我禁用这两个 类 的解决方案:createObject()
的 java.lang.Runtime
和 java.lang.ProcessBuilder
。
注意:我也尝试过 sanbox 中的文件限制和 os 权限,但不幸的是,它们似乎只适用于 I/O 文件操作,我不能弄乱系统库的安全策略因为它们可能会被 ColdFusion 内部使用。
根据@Leigh and @Miguel-F 的有用建议,我尝试实现了 Security Manager
和 Policy
。结果如下:
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.
}
我想创建一个安全的 ColdFusion 环境,为此我使用了多个沙箱配置。使用友好的管理员界面可以轻松完成以下任务:
- 限制 CFtag,例如: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();
问题是我找不到任何允许我禁用这两个 类 的解决方案:createObject()
的 java.lang.Runtime
和 java.lang.ProcessBuilder
。
注意:我也尝试过 sanbox 中的文件限制和 os 权限,但不幸的是,它们似乎只适用于 I/O 文件操作,我不能弄乱系统库的安全策略因为它们可能会被 ColdFusion 内部使用。
根据@Leigh and @Miguel-F 的有用建议,我尝试实现了 Security Manager
和 Policy
。结果如下:
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.
}