本节书摘来异步社区《Java编码指南:编写安全可靠程序的75条建议》一书中的第1章,第1.16节,作者:【美】Fred Long(弗雷德•朗), Dhruv Mohindra(德鲁•莫欣达), Robert C.Seacord(罗伯特 C.西科德), Dean F.Sutherland(迪恩 F.萨瑟兰), David Svoboda(大卫•斯沃博达),更多章节内容可以访问云栖社区“异步社区”公众号查看。

指南16:避免授予过多特权

Java安全策略为代码授予权限,用来允许指定代码访问特定的系统资源。一个被授予许可的代码源(CodeSource类型的对象),是由代码位置(URL)和证书引用组成的,该证书包含公钥以及与之对应的私钥,用来对代码进行数字签名, 代码只有在被某证书数字签名之后,才能关联到该证书引用。代码只有在被某证书数字签名之后,才能关联到该证书引用。保护域(protection domain)包含一个CodeSource对象,以及CodeSource中的代码被授予的权限,这是由当前生效的安全策略所决定的。因此,用相同的密钥来进行签名的、来自相同URL的类,会被放置在相同的保护域中。一个类仅仅属于一个保护域。具有相同权限、但来自不同代码源的类,属于不同的保护域。

每个Java类都运行在由代码源决定的恰当的保护域里。运行在安全管理器之下的任何代码,在执行任何安全相关的操作时,都必须被授予特定的权限,如读或者写一个文件时必须要有执行文件读或者写的权限。通过使用AccessController.doPrivileged()方法,特权代码可以代表无特权的调用者,访问特权资源,这是很有必要的。例如,当一个系统工具程序需要代表用户打开一个字体文件用来显示一个文档,但是应用程序本身缺乏权限做这样的事的时候。为了执行该操作,系统工具程序会使用它的全部特权来获取这个字体,而忽略调用者的特权。特权代码运行在与代码源相关的所有特权保护域里。这些特权往往超出了执行特权操作的需要。理想的情况下,代码应该被授予恰好满足其完成操作所需特权的最小集合。

指南19中描述了另外一种用来消除多余特权的方法。

违规代码示例

下面的违规代码示例显示了一个库方法,通过使用包装器方法performActionOnFile()来允许调用者执行授权操作(读文件)。

private FileInputStream openFile() {final FileInputStream f[] = { null };AccessController.doPrivileged(new PrivilegedAction() {public Object run() {try {f[0] = new FileInputStream("file");} catch(FileNotFoundException fnf) {// Forward to handler}return null;}}); return f[0];
}// Wrapper method
public void performActionOnFile() {try (FileInputStream f = openFile()){// Perform operation} catch (Throwable t) {// Handle exception}
}```
在这个例子中,对可信代码授予的特权超出了读取一个文件的真实需要,即便是需要读取文件,也只需要为doPrivileged()代码块授权。因此,这段代码为代码块提供了多余的特权,从而违反了最小特权原则。####合规解决方案
双参数形式的doPrivileged()方法从调用者那里接受一个作为第二个参数传递的AccessControlContext对象,并将所包含代码的特权限制在保护域特权和上下文权限的交集中。因此,当调用者只希望授予代码读取文件权限时,可以提供一个只有文件读取权限的上下文。一个被适当授予文件读取权限的AccessControlContext,可以作为一个内部类:

private FileInputStream openFile(AccessControlContext context) {
 if (context == null) {
  throw new SecurityException("Missing AccessControlContext");
 }

 final FileInputStream f[] = { null };
 AccessController.doPrivileged(
  new PrivilegedAction() {
   public Object run() {
    try {
     f[0] = new FileInputStream("file");
    } catch (FileNotFoundException fnf) {
     // Forward to handler
    }
    return null;
   }
  },
  // Restrict the privileges by passing the context argument
  context);
  return f[0];
}

private static class FileAccessControlContext {
 public static final AccessControlContext INSTANCE;
 static {
  Permission perm = new java.io.FilePermission("file", "read");
  PermissionCollection perms = perm.newPermissionCollection();
  perms.add(perm);
  INSTANCE = new AccessControlContext(new ProtectionDomain[] {
   new ProtectionDomain(null, perms)});
 }
}

// Wrapper method
public void performActionOnFile() {
 try {
  final FileInputStream f =
   // Grant only open-for-reading privileges
   openFile(FileAccessControlContext.INSTANCE);
   // Perform action
 } catch (Throwable t) {
  // Handle exception
 }
}`
如果调用者缺乏创建一个适当的AccessControlContext的权限,那么可以通过请求AccessController.getContext()来创建一个这样的实例。

适用性

未能遵循最小特权原则可能导致不可信、未授权的代码执行意想不到的特权操作。然而,过细地限制特权会增加程序复杂性。这些增加的复杂性和相应减少的可维护性必须同安全改进做出利弊权衡。

《Java编码指南:编写安全可靠程序的75条建议》—— 指南16:避免授予过多特权...相关推荐

  1. 《Java编码指南:编写安全可靠程序的75条建议》—— 指南20:使用安全管理器创建一个安全的沙盒...

    本节书摘来异步社区<Java编码指南:编写安全可靠程序的75条建议>一书中的第1章,第1.20节,作者:[美]Fred Long(弗雷德•朗), Dhruv Mohindra(德鲁•莫欣达 ...

  2. 《Java编码指南:编写安全可靠程序的75条建议(英文版)》—— 2.7 修复错误...

    本节书摘来异步社区<Java编码指南:编写安全可靠程序的75条建议(英文版)>一书中的第2章,第2.7节,作者:[美]Fred Long(弗雷德•朗),Dhruv Mohindra(德鲁• ...

  3. 《Java编码指南:编写安全可靠程序的75条建议》—— 指南19:对细粒度的安全定义自定义安全权限...

    本节书摘来异步社区<Java编码指南:编写安全可靠程序的75条建议>一书中的第1章,第1.19节,作者:[美]Fred Long(弗雷德•朗), Dhruv Mohindra(德鲁•莫欣达 ...

  4. Java //PP2.6 编写一个应用程序,将英里转换为千米(1英里等于1.60935千米)。以浮点数类型读取用户输入的英里数

    Java程序设计教程(第七版) John Lewis & William Loftus 电子工业出版社 PP2.6 编写一个应用程序,将英里转换为千米(1英里等于1.60935千米).以浮点数 ...

  5. 如何有效编写软件的75条建议

    1. 你们的项目组使用源代码管理工具了么?   应该用.VSS.CVS.PVCS.ClearCase.CCC/Harvest.FireFly都可以.我的选择是VSS. 2. 你们的项目组使用缺陷管理系 ...

  6. 【转】初学入门:如何有效编写软件的75条建议

    1. 你们的项目组使用源代码管理工具了么?  应该用.VSS.CVS.PVCS.ClearCase.CCC/Harvest.FireFly都可以.我的选择是VSS. 2. 你们的项目组使用缺陷管理系统 ...

  7. Java实验:编写网络聊天程序(图形界面)

    课程名称 高级Java程序设计 实验项目 Java网络编程 实验目的: 使用客户机/服务器模式.基于TCP协议编写一对多"群聊"程序.其中客户机端单击"连接服务器&quo ...

  8. 我密集面试了若干位Java后端的候选人,给广大程序员的一点建议

    摘要 在上周,我密集面试了若干位Java后端的候选人,工作经验在3到5年间.我的标准其实不复杂: 第一能干活: 第二Java基础要好: 第三最好熟悉些分布式框架. 我相信其它公司招初级开发时,应该也照 ...

  9. 编写一个游戏程序(如连连看、五子棋、2048、扫雷、泡泡堂、太鼓)或其他你觉得有意思的程序。

    JAVA程序设计: 编写一个游戏程序(如连连看.五子棋.2048.扫雷.泡泡堂.太鼓)或其他你觉得有意思的程序. /// 完成内容如下: (1)可以顺利编译的项目源码: (2)可以直接运行的.exe文 ...

最新文章

  1. MS SQL Server和MySQL区别
  2. 当客户说“你们的价格太高了”
  3. ArrayList刷题总结
  4. 信守承诺:JAX-RS API的基于合同的测试
  5. 数据可视化机器学习工具在线_为什么您不能跳过学习数据可视化
  6. MySQL 8.0.22 源码编译安装全过程
  7. recovery升级是显示进度条_注意!税控系统软件升级了,还有疑问看这里!
  8. syslog工具_07 Docker 可视化管理和监控工具
  9. Nginx只允许域名访问网站,禁止使用IP 访问80,443端口
  10. 背离、背驰的区别及简单的判断方法
  11. WES2009创建开发
  12. js字符与ascii码转换
  13. 英语教师计算机研修总结,英语教师个人研修总结范文
  14. java安卓app开发教程_[Android教程] Cordova开发App入门(一)创建android项目
  15. 国内android应用商城中程序隐私泄露分析,基于数据生命周期的Android应用程序隐私泄露分析技术研究...
  16. 苹果:第三方安装软件或导致严重隐私、安全风险
  17. Java中JVM虚拟机详解
  18. 3、中小企业网络架构-接入层交换机基本配置
  19. 全国实时天气预警查询
  20. 《图解UE4渲染体系》Part 0 引擎基础

热门文章

  1. HTTP POST发消息
  2. 我们活在世界上,不是为了求人们原谅。
  3. 一些常用算法 练手的的代码
  4. 数据倾斜是什么以及造成的原因?
  5. apipost使用mock随机获取多组数据中的一组数据进行测试
  6. http请求中get和post方法的区别
  7. JMeter对数据库的更新操作
  8. api 另一窗体 之上_12 个设计 API 的安全建议,不要等出事儿了“捶胸顿足”
  9. PreparedStatement对象
  10. ssh连接虚拟机的linux_openstack系列之运维排障:虚拟机SSH连接失败