知识大全 探索Java应用程序的安全需求

Posted

篇首语:学者之所以是学者,不是因为他博学,而是因为他一直保有求知欲。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 探索Java应用程序的安全需求相关的知识,希望对你有一定的参考价值。

探索Java应用程序的安全需求  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!

  我们知道 维护应用程序的安全并不简单 不过我们也清楚 完全可以采取一些措施来缓解安全缺陷带来的风险 如果我们是网络工程师 就可以将精力投入网络分区和包过滤器方面的知识 如果用C语言编程 我们就保护程序以防止缓冲区溢出 如果用Java编程 我们就考虑在安全管理器的保护之下运行应用程序 每种情况下 我们都用最佳实践中获得的知识来战胜无意造成的系统故障

  Java应用程序的安全条款 是本文所讨论内容的依据 我们的讨论把重点放在Java安全管理器方面 这是Java安全架构主题中的一个很小的子集

  安全管理器是 java lang SecurityManager类或扩展自该类的一个类 且它在运行时检查某些应用程序操作的权限 一旦受到安全管理器的控制 应用程序就只能执行那些由相关安全策略特别准许的操作 默认情况下 该策略是在纯文本 策略文件 中指定的 所涉及的操作包括 将文件写入特定目录 写协同属性 建立到特定主机的网络连接 这里列出的只是其中的一小部分 仅用一个简单的JVM命令行选项即可迫使Java应用程序在一个安全管理器下运行 而且安全策略文件可以由任何文本编辑器轻松创建

  虽然编辑这样一个安全策略文件并添加各种相关规则并不难 不过获得策略制订权会更具有挑战性 而且尽管没人可以为我们提供这样的策略制订权 但工具能帮助我们理解那个策略应该是什么 开发并使用这样的工具是我们即将着手的工作 一旦我们有了它所发现的更宽泛 更细粒度的策略 就可以在开发产品运行时策略时将其作为起点 或者为了更好地理解和认识应用程序的安全需求而研究它

  本文的核心代码是一个通用的安全管理器 要使用它就需要有Sun的JSE JVM 为了从特定的Java系统类中获得私有成员数据 从安全管理器对Java Reflecition API的依赖性中派生JSE (Java Standard Edition)的需求 由于缺乏对管理器运行所需的某有成员数据的公共访问 因而需要使用Reflection API 使用私有成员反射的后果就是管理器与其运行所在的的JVM内部紧密相关 但这算不上什么严重的后果 因为管理器是一个开发工具 而不是产品组件 一旦管理器提出一个策略制订起点 我们就可以采用那个策略 并在任何现代JVM上运行遵从它的应用程序

默认Java安全管理器

  现代文献中所编写 讨论及引用的绝大多数Java代码都代表着在不受安全管理器限制的情况下运行的应用程序 因而这种应用程序对所有的机器资源包括磁盘 网络和应用程序关闭等有完全访权限 不过这种宽泛的访问权限很容易受到限制 仅通过在JVM命令行上设置Djava security manager 选项 就可以迫使应用程序在默认的Java安全管理器下运行

  看一下下面这个简单的应用程序 其目的是读取和打印用户的主目录

  public class PrintHome public static void main(String[] argv) System out println(System getProperty( user home ));

  编译代码 并让它在默认安全管理器的限制下运行

  $ cd $HOME/Projects/CustomSecurityManager $ javac PrintHome java $ java Djava security manager PrintHome Exception in thread main java security AccessControlException: access denied (java util PropertyPermission user home read) at PrintHome main(PrintHome java: )

  上面的应用程序中未能获得并打印 user home属性 而且出于代码可读性方面的考虑 我们省略了栈跟踪中的绝大部分 该应用程序未能执行是因为随着缺省安全策略运行的缺省安全管理器禁止访问user home属性 这个特权必须在运行策略文件中具体给出

  创建一个包含单一规则的策略文件policy txt

  grant codeBase file:/home/cid/Projects/CustomSecurityManager/ permission java util PropertyPermission user home read ;

  重新运行该应用程序 对策略文件的引用解决了对user home的读访问问题

  $ java Djava security policy=policy txt Djava security manager PrintHome /home/cid

  注意到 我们通过设置系统属性java security policy=policy txt来将JVM引用到策略文件中 我们还假定PrintHome类位于/home/cid/Projects/CustomSecurityManager目录中 policy txt 文件中的规则允许任何包含在那个目录中文件的代码去读取系统属性user home 结果 规则允许PrintHome像预期的那样运行 包含代码的文件就称其为代码库 因此代码库就是一个类文件或jar文件

安全策略剖析工具 ProfilingSecurityManager

  正如我们前面提到的 创建一个安全策略文件并不难 即使像 策略池 这样的实用工具可提供协助 而且在策略文件中允许有很强大的 语法快捷方式 它允许创建有表现力的 高效的规则 使用这种高级规则符号 我们可以指定 比如说 递归引用整个目录树的代码库URL 这种递归 URL 规范不仅非常有用 方便 而且能够向代码阅读者屏蔽掉应用程序对资源需求的真实 细粒度的深度 这正是我们寻求的细节

  因此我们的目标是双方面的 首先 我们希望在安全策略的限制下运行应用程序 或者至少说 我们希望确定该应用程序的安全需求 其次 我们需要一种程序性的方法来确定那些需求

  带着这些目标 我们来介绍定制的安全管理器secmgr ProfilingSecurityManager 这个类扩展了java lang SecurityManager 但未实施本文至此所讨论的安全策略 不过 据说它会实施此类安全策略如果应用程序可以获得在运行时访问它所请求的一切内容的权利 那么我们可接受这种说法 将其转换成运行时安全策略的起点 这样一来 我们的两个目标就都可以实现

  为了使用ProfilingSecurityManager 首先编译并有策略地将其放在自己的jar文件中(源代码可以在 资源 这一节找到) 单独将ProfilingSecurityManager放到它自己的jar文件中将允许我们过滤并取消由一些源于它自己jar文件代码库的活动所产生的输出规则 ProfilingSecurityManager通过以下代码可以知道自己独有的代码库

  if( url toString() equals(thisCodeSourceURLString) ) return null;

  从而可以避免自身报告 同时编译该工具 并将其制成 jar

  $ mkdir p classes lib $ rm rf classes/* lib/* $ javac d classes ProfilingSecurityManager java $ jar cf lib/psm jar C classes secmgr/manager $ rm rf classes/secmgr/manager

  在我们继续讲下去之前 应该讲一下如何激活ProfilingSecurityManager 使之成为应用程序安全管理器 回想前面 我们通过设置一个无对应属性值的系统属性Djava security manager来促使应用程序在缺省的Java安全管理器限制下运行 我们需要进一步推广这种措施 并通过给系统属性赋值将定制安全管理器指定为安全管理器 Djava security manager=secmgr ProfingSecurityManager 因此被激活之后 ProfilingSecurityManager将写入System out 策略文件中需要的这些规则允许应用程序在无需抛出安全违反异常的情况下运行 然而 这些规则不能被处理成最终可用的形式 直到应用程序在ProfilingSecurityManager下完成其运行为止 为什么呢?因为我们知道仅在那时应用程序才完成了以检查资源为目的的请求访问 所以为了使应用程序在ProfilingSecurityManager下完成运行时处理并整理这些规则 我们提供了一个简单的Perl脚本parsecodebase pl(见 示例代码) 以便以易于阅读的格式聚集 格式化 输出由代码库分类并组合的规则

  好了 我们现在用指定为安全管理器的ProfilingSecurityManager 和由parsecodebase pl处理的规则输出来运行简单的 PrintHome 程序 会产生如下结果

  $ java cp :lib/psm jar Djava security manager=secmgr ProfilingSecurityManager PrintHome > raw out $ parsecodebase pl < raw out > policy txt $ cat policy txt grant codeBase file:/home/cid/Projects/CustomSecurityManager/ permission java util PropertyPermission user home read ; ; $ java cp Djava security manager Djava security policy=policy txt PrintHome /home/cid

  我们再次看到 ProfilingSecurityManager同时满足了我们的两个设计目标

    我们的应用程序使用定义良好 特定于应用程序的策略在安全管理器下运行 我们通过编程的方式确定了那个策略

  ProfilingSecurityManager是如何工作的呢?ProfilingSecurityManager重写了java lang SecurityManager 的 checkPermission 方法的两个版本 这个方法的两种形式是用于检查应用程序请求访问哪个资源或活动的中央枢纽 被重写的checkPermission方法总是不需丢弃异常而返回——本意是 允许访问 —不过条件是它们必须建立并输出规则 以允许为其操作负责的活动能首先得到调用

一个更复杂的例子 剖析Tomcat Web应用程序

  先将那个简单实例暂且搁置 我们来观察ProfilingSecurityManager的一个复杂应用 剖析Tomcat Web应用程序 通过传送 security 选项到标准启动脚本 Tomcat可在默认Java安全管理器下运行

  $ $CATALINA_HOME/bin/startup sh security

  传送 security 选项到startup sh 会导致对拥有同样 security 选项的$CATALINA_HOME/bin/catalina sh 的调用 $CATALINA_HOME/bin/catalina sh 实际上是调用Java来运行Tomcat 引导类 apache catalina startup Bootstrap 的一种脚本 在这种情况下 将进一步受到$CATALINA_HOME/conf/catalina policy中所规定默认策略的限制 如果我们将调用停留在此处 Tomcat将在由默认提供策略所限制的默认Java安全管理器下运行 不过为了剖析Tomcat以及它可能包含的Web应用程序 我们需要稍微多做一些工作 为了用ProfilingSecurityManager剖析Web应用程序 我们必须开发新的Tomcat启动脚本 新启动脚本是一个临时设备 而且仅用于剖析 之后被废弃

  为 $CATALINA_HOME/bin/catalina sh做一个备份副本 在脚本顶部附近的 $CATALINA_HOME/bin/catalina sh 中近插入shell命令set x 然后启动Tomcat 保存显示的shell执行命令到一个包含临时启动脚本的文件中 停止Tomcat 编辑临时脚本 指定ProfilingSecurityManager 为安全管理器并修改类路径来定位它

  以下是在Linux操作系统下的Tomcat 中 我们为使用 ProfilingSecurityManager进行编辑之前的临时启动脚本 略经调整和格式化

  #!/bin/sh log=$CATALINA_HOME/logs/catalina out /java/jdk/jdk _ /bin/java \\ Djava util logging manager= apache juli ClassLoaderLogManager \\ Djnfig file=/home/tomcat/tomcat/conf/logging properties \\ Djava endorsed dirs=/home/tomcat/tomcat/mon/endorsed \\ classpath :/home/tomcat/tomcat/bin/bootstrap jar:\\ /home/tomcat/tomcat/bin/mons logging api jar \\ Djava security manager \\ Djava security policy==/home/tomcat/tomcat/conf/catalina policy \\ Dcatalina base=/home/tomcat/tomcat \\ Dcatalina home=/home/tomcat/tomcat \\ Djava io tmpdir=/home/tomcat/tomcat/temp \\ apache catalina startup Bootstrap start >> $log \\ >& &

  为了使用 ProfilingSecurityManager而进行编辑后 该启动脚本如下所示

  #!/bin/sh log=$CATALINA_HOME/logs/catalina out PATHTOPSM=$HOME/lib/psm jar # make sure the profiler jar file is here /java/jdk/jdk _ /bin/java \\ Djava util logging manager= apache juli ClassLoaderLogManager \\ Djnfig file=/home/tomcat/tomcat/conf/logging properties \\ Djava endorsed dirs=/home/tomcat/tomcat/mon/endorsed \\ classpath $PATHTOPSM:/home/tomcat/tomcat/bin/bootstrap jar:\\ /home/tomcat/tomcat/bin/mons logging api jar \\ Djava security manager=secmgr manager ProfilingSecurityManager \\ Djava security policy==/home/tomcat/tomcat/conf/catalina policy \\ Dcatalina base=/home/tomcat/tomcat \\ Dcatalina home=/home/tomcat/tomcat \\ Djava io tmpdir=/home/tomcat/tomcat/temp \\ apache catalina startup Bootstrap start >> $log \\ >& &

  这两个脚本的不同点在于新临时版本

    增加了类路径以指向ProfilingSecurityManager类的位置 即$HOME/lib/psm jar 中 在 Djava security manager参数中指定ProfilingSecurityManager为安全管理器

  现在我们可以开始剖析了 用临时启动脚本启动 Tomcat 促使相关web应用程序覆蓋那些会在生产中被覆蓋的代码 以此考验它们的速度 用代码覆蓋Web应用程序是一个公认的 难以实现的命令 而且可能仅有部分可以实现 停止Tomcat 通过parsecodebase pl运行$CATALINA_HOME/logs/catalina out 如下所示 同时将处理过的规则保存到到 policy txt中

  $ parsecodebase pl < $CATALINA_HOME/logs/catalina out > policy txt

  清单 处理由Tomcat和其中所包含的任意已执行Web应用程序生成的规则

  注意 ProfilingSecurityManager只能为那些在剖析过程中执行的代码生成规则 它会探测理论上可以在随机运行实例中触及的所有代码分支 而不检查类文件中的字节码 这样的字节码分析可能是将来的一个研究领域 我们将加以补充 但它不能替换由 ProfilingSecurityManager 做的运行时分析

  对随Tomcat提供的策略文件 $CATALINA_HOME/conf/catalina policy 的检查表明 Tomcat  ( Catalina )系统代码库获得了所有平台的权限 事实上 ProfilingSecurityManager会发现Tomcat系统类的这些相同规则 但会以细粒度的方式指定它们 ProfilingSecurityManager发现的关于Tomcat系统类的规则应从policy txt中手动删除

  删除了 Tomcat系统规则后 仍然保留在policy txt中的规则就是生产安全策略的起点 这些规则表示Web应用程序的安全需求 应仔细检查这些规则中的每一条 以了解其用途 并确保它与我们的应用程序目标相一致 确信有好的草案策略时 为$CATALINA_HOME/conf/catalina policy做一个备份副本 并从 policy txt中将新草案规则整合进来 然后用 security 选项集回复到原来的 Tomcat 启动脚本 继续测试

结束语

  在Java安全管理器下运行应用程序可以增加代码的健壮性 而且 虽然获得安全策略制订权是一项艰巨的挑战 不过这样做会让我们安心 因为代码将在我们所规定的安全约束的限制下运行 ProfilingSecurityManager可以为我们提供对应用程序所请求访问的资源集的充分可见度 从而帮助我们获得策略制订权

资源

    示例代码 本文引用的示例代码包括 ProfilingSecurityManager 和 parsecodebase pl Subverting Java Access Protection for Unit Testing 主要讨论Java 映射基础 Tomcat: The Definitive Guide 额外的一些Tomcat 安全性的详细介绍 Java Permissions list Java 安全性架构文档

  作者简介

Mark Petrovic是一位技术专家和软件开发人员 cha138/Article/program/Java/hx/201311/26431

相关参考

知识大全 如何实现网页程序自动登录(java)

  我不得不使用好几个系统都是B/S结构的每次登录都需要输入用户名和密码觉得非常麻烦考虑到其他同事也会有这样的需求不妨就写个自动登录的程序吧之前也考虑过使用单点登录几经尝试之后还是放弃了  我习惯使用

知识大全 探索Java语言与JVM中的Lambda表达式

探索Java语言与JVM中的Lambda表达式  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  L

知识大全 驾驭“野马”-- 探索Java SE 6的一些新特性

驾驭“野马”--探索JavaSE6的一些新特性  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  s

知识大全 学了java,可以从事什么职业

学了java,可以从事什么职业?1.互联网在互联网方向的应用非常多,如果细分的话可以分为很多种。目前采用Java开发互联网网站及应用的公司越来越多,这也增加了Java开发工程师的需求。像京东的一些后端

知识大全 用java写一个登陆程序,可以与服务器连接,登陆成功后跳转到服务器网站上

用java写一个登陆程序,可以与服务器连接,登陆成功后跳转到服务器网站上楼主,这样的需求,不管如何都要有一个API说明的吧,根据实际的情况写相应的网络程序ftp服务器无法登陆,同一个服务器上的网站可以

知识大全 EntityFramework用法探索:线程安全实践

EntityFramework用法探索:线程安全实践  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!

知识大全 编写高效的线程安全类

 在语言级支持锁定对象和线程间发信使编写线程安全类变得简单本文使用简单的编程示例来说明开发高效的线程安全类是多么有效而直观  Java编程语言为编写多线程应用程序提供强大的语言支持但是编写有用的没有错

知识大全 Delphi深度探索-CodeSite应用指南

Delphi深度探索-CodeSite应用指南  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  D

知识大全 PHP程序加速探索之缓存输出

PHP程序加速探索之缓存输出  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  内容缓存输出PEAR

知识大全 PHP程序加速探索之服务器负载测试

PHP程序加速探索之服务器负载测试  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  服务器负载太大