51Testing软件测试论坛

 找回密码
 (注-册)加入51Testing

QQ登录

只需一步,快速开始

微信登录,快人一步

手机号码,快捷登录

查看: 2004|回复: 0
打印 上一主题 下一主题

由Fortify扫描结果而引发的java安全模型分析

[复制链接]

该用户从未签到

跳转到指定楼层
1#
发表于 2018-4-16 13:26:20 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
最近公司在搞security audit,项目里的applet被Fortify扫描后报了一个安全隐患,具体信息如下:
  1. Abstract:
  2. Non-final methods that perform security checks can be overridden in ways that bypass security checks.
  3. Explanation:
  4. If a method is overriden by a child class, the child class can bypass security checks in the parent class.
  5. Example: In the following code, doSecurityCheck() performs a security check and can be overriden by a child class.
  6. public class BadSecurityCheck {
  7.         private int id;
  8.         public BadSecurityCheck() {
  9.                 doSecurityCheck();
  10.                 id = 1;
  11.         }
  12.         protected void doSecurityCheck() {
  13.                 SecurityManager sm = System.getSecurityManager();
  14.                 if (sm != null) {
  15.                         sm.checkPermission(new SomePermission("SomeAction"));
  16.                 }
  17.         }
  18. }
复制代码

这个问题就是说我在applet类的init()方法代码里用到了AccessController.checkPermission()方法,而由于我的类
是public非final的,所以hacker们可以自己写一个子类继承后重写init方法,绕过安全检查过程去干一些坏事。

首先我觉得这警告有一定道理,所以打算把类改成final的,但是我又想不通一个applet如何继承重写以及会有
什么坏事可干,因为我的程序init()入口处是这样的:

  1. [java] view plaincopyprint?
  2. //check file permission  
  3. Permission sockPerm=new SocketPermission("*","accept,connect,listen");  
  4. Permission filePerm=new FilePermission("<<ALL FILES>>","read");  // what if (in linux) the user cannot read all files  
  5. try{  
  6.     AccessController.checkPermission(sockPerm);  
  7.     AccessController.checkPermission(filePerm);   // the applet cannot successfully run if this failed  
  8. }catch(AccessControlException ace){  
  9.     this.hintText=LocaleUtils.getResourceValue("mainpanel.hinttext.unauthorized");  
  10.     permissionAllowed=false;  
  11. }  
复制代码

在applet启动时先去检查自己是否有相关权限去读客户端的文件,如果没有就提示用户。所以我没想到这会有
什么安全隐患,然后我查阅了java的相关资料,试着去了解java的安全机制到底是怎样的。

首先,只针对java applet,JVM安全策略是这样的:

1. 作为从网络下载到的java代码,applet默认是不受信任的,在客户端没有任何读写权限,完全运行在沙箱里。

2. 为了使applet可以和客户本地文件交互,可以为applet进行签名,签过名的applet有读写文件的权利,但是如果
该签名是非信任的,也就是没有认证的,会在加载applet时弹出对话框提示用户,只有用户允许才能获得权限。

3. 如果是认证可信签名,则可以完全正常允许。


了解了applet的权限控制后,又进一步了解了java的安全机制。实际上, Java 将执行程序分成本地和远程两种,
本地代码默认视为可信任的,而远程代码(如applet)则被看作是不受信的。对于授信的本地代码,可以访问一
切本地资源。

这里的权限控制,是由java安全管理器(Security Manager)管理的,远程代码JVM自动启动管理,而本地默认
不启动。


这里只做一个最简单和最基础的演示, 比如我们在平时写java代码文件操作时,很少考虑权限问题,以及为什么
我们很少用的AccessController,因为它默认是不开启的,如:

  1. [java] view plaincopyprint?
  2. try {  
  3.     // try to create a file at $path  
  4.     File fs = new File("foo");  
  5.     fs.createNewFile();  
  6. } catch (AccessControlException e) {  
  7.     e.printStackTrace();  
  8. }  
复制代码

其实是可以正常执行的, 但如果加了一条
  1. [java] view plaincopyprint?
  2. System.setSecurityManager(new SecurityManager());  
  3. try {  
  4.     // try to create a file at $path  
  5.     File fs = new File("foo");  
  6.     fs.createNewFile();  
  7. } catch (AccessControlException e) {  
  8.     e.printStackTrace();  
  9. }  
复制代码


就会抛出异常, 原因就像前面说的, 本地默认安全管理器是没有开启的,所以我们的程序有所有权限,但一旦
你打开了SecurityManager,你就失去了这些权限,需要重新获得才可以,需要用到权限提升方法doProvileged
,整个Security Manager以及访问控制的运行机制,还是比较复杂的,一时也说不清, 更具体的还要靠自己慢慢
探索了。

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏
回复

使用道具 举报

本版积分规则

关闭

站长推荐上一条 /1 下一条

小黑屋|手机版|Archiver|51Testing软件测试网 ( 沪ICP备05003035号 关于我们

GMT+8, 2024-11-23 19:35 , Processed in 0.065791 second(s), 22 queries .

Powered by Discuz! X3.2

© 2001-2024 Comsenz Inc.

快速回复 返回顶部 返回列表