本节书摘来异步社区《java编码指南:编写安全可靠程序的75条建议》一书中的第1章,第1.19节,作者:【美】fred long(弗雷德•朗), dhruv mohindra(德鲁•莫欣达), robert c.seacord(罗伯特 c.西科德), dean f.sutherland(迪恩 f.萨瑟兰), david svoboda(大卫•斯沃博达),更多章节内容可以访问云栖社区“异步社区”公众号查看。
默认的securitymanager会检查给定方法的调用者是否具有足够的继续执行动作的权限。动作定义在java安全架构的访问级别,需要特定的权限才能执行。例如,java.io.filepermission类的动作是读、写、执行和删除[api 2013]。“权限描述和风险”指南(permission descriptions and risks guide)[oracle 2011d]列举了默认的权限和为java代码授予这些权限有关的风险。
有时候,我们需要的限制比默认安全管理器所能提供的还要强。当不存在对应的默认权限且未能提供自定义的权限时,可能会导致特权升级漏洞,从而允许不可信的调用者执行限制操作或动作。
本指南讨论了过多权限的问题,有关解决这个问题的另外一个办法,参见指南16。
下面的违规代码示例包含一个特权代码块,用来执行两个敏感操作:加载一个库;设置默认异常处理程序。
class loadlibrary {
private void loadlibrary() {
accesscontroller.doprivileged(
new privilegedaction() {
public object run() {
// privileged code
system.loadlibrary("mylib.so");
// perform some sensitive operation like
// setting the default exception handler
myexceptionreporter.setexceptionreporter(reporter);
return null;
}
});
}
}
final class myexceptionreporter extends exceptionreporter {
public void setexceptionreporter(exceptionreporter reporter) {
securitymanager sm = system.getsecuritymanager();
if(sm != null) {
sm.checkpermission(
new exceptionreporterpermission("exc.reporter"));
}
// proceed to set the exception reporter
}
// ... other methods of myexceptionreporter
final class exceptionreporterpermission extends basicpermission {
public exceptionreporterpermission(string permname) {
super(permname);
// even though the actions parameter is ignored,
// this constructor has to be defined
public exceptionreporterpermission(string permname,
string actions) {
super(permname, actions);
}<code>`</code>
策略文件需要授予两个权限:将exceptionreporterpermission权限授予exc.reporter;将runtimepermission权限授予loadlibrary.mylib。以下策略文件假设上述资源位于windows系统的c:package目录下。