Tomcat是一个Web容器,我们开发的Web项目运行在Tomcat平台,这就好比将一个应用嵌入到一个平台上面运行,要使嵌入的程序能正常运行,首先平台要能安全正常运行。并且要最大程度做到平台不受嵌入的应用程序影响,两者在一定程度上达到隔离的效果。Tomcat与Web项目也是要最大程度隔离,使Tomcat平台足够安全。

我们先看看Tomcat可能存在哪些安全威胁。

(1) 在web应用的jsp页面或Servlet中使用System.exit(1);

假如你是一个老板,但是平时对待员工苛刻,工资又老是不准时发,承诺给员工的福利又做不到,所有员工敢怒不敢言,在背后严重鄙视你。小明实在看不下去准备离职了,他觉得要做点事情报复下你这没人情味的老板,作为程序员的他,于是敲起了几行代码作为离别礼物:

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

Date date = sdf.parse("2019-01-01 00:00:00");

Date now = new Date();

if (now.after(date)){

    System.exit(1);

}

在Servlet中的这几行代码,平时运行一点事情都没有,但是他就像个定时炸弹,在小明庆祝他离职五周年时,你的公司的系统就时不时得停止服务,并且还很难找出问题的所在。

(2) 在web应用中调用Tomcat内部核心代码实现类,特别是静态类;

Tomcat中有些代码是可以给外部调用,而有些核心代码为避免给Tomcat带来威胁甚至是崩溃的危险,需要控制外部程序的访问。

以上两种情况,都可能在Tomcat运行时导致Tomcat罢工。针对这些情况,我们有必要使用SecurityManager来保护服务器不受类似木马的servlet、jsp和标签库等得影响,使服务器多一层保护,能运行地更加安全可靠。

    Tomcat中有一般会使用到的权限许可有以下这些:

 java.util.PropertyPermission - 控制读/写Java虚拟器的属性,如java.home。

 java.lang.RuntimePermission - 控制使用一些系统/运行时(System/Runtime)的功能,如exit()和exec()。它也控制包(package)的访问/定义。

 java.io.FilePermission - 控制对文件和目录的读/写/执行操作。

 java.net.SocketPermission - 控制使用网路sockets连接。

 java.net.NetPermission - 控制使用multicast网路连接。

 java.lang.reflect.ReflectPermission - 控制使用reflection来对类进行检视。

 java.security.SecurityPermission - 控制对安全方法的访问。

 java.security.AllPermission - 给予所有访问权限。





毫无疑问,为了保证Tomcat的安全性,Tomcat启动时也开启了安全管理器,它采用的是默认的安全管理器——SecurityManager。在Tomcat启动的批处理文件中能找到-Djava.security.manager -Djava.security.policy==%CATALINA_BASE%\conf\catalina.policy,但Tomcat并没有使用默认的策略文件,而是指定一个catalina.policy作为策略文件。下面列出Catalina.policy文件有代表性的授权语句:

grant codeBase "file:${java.home}/lib/-" {

    permission java.security.AllPermission;

};

grant codeBase "file:${catalina.home}/bin/tomcat-juli.jar" {

permission java.io.FilePermission "${catalina.base}${file.separator}logs", "read, write";

    permission java.lang.RuntimePermission "shutdownHooks";

    permission java.util.PropertyPermission "catalina.base", "read";

};

grant {

    permission java.lang.RuntimePermission "accessClassInPackage.org.apache.tomcat";

};

上面有三个grant语句,第一个授权表示的意义比较简单,java安装路径下的lib目录及其子目录下的jar包拥有所有的权限。符号说明:*表示所有文件,-表示所有文件及其子目录下的文件。第二个grant是对Tomcat安装路径下bin目录的tomcat-juli.jar包进行授权,包括对tomcat安装目录下logs目录的读写权限、关闭钩子权限、catalina.base系统变量的读取权限。第三个grant表示授权对org.apache.tomcat包里面的类访问权限。

针对accessClassInPackage权限有必要展开详细讲解,还有一个类似的权限defineClassInPackage,由于默认的情况下是所有包都是可以被访问调用的,如果要对一些包进行访问控制,可通过以下几个步骤使应用具备这两种权限的安全检查。

首先,设置安全属性,告诉安全管理器哪些包需要进行访问权限检查,Security.setProperty

("package.definition","需要检查的包,多个包用逗号分隔")、Security.setProperty("package.access", "需要检查的包,多个包用逗号分隔")。

其次,配置策略文件policy,对指定类或包配置访问指定包的权限,例如

grant codeBase "file:${catalina.home}/webapps/manager/-"{

permission java.lang.RuntimePermission"accessClassInPackage.org.apache.tomcat";

};

指定${catalina.home}/webapps/manager/目录及其子目录下得文件都有访问org.apache.tomcat包的权限。格式是"accessClassInPackage.包路径"。

最后,如果你想检查此类是否有某个包的访问权限,可以显式地使用System.getSecurityManager(). checkPackageAccess("包路径");否则会在类加载器加载某个类时由loadClass方法触发权限检查。如果没权限则抛出SecurityException异常。

package.definition跟package.access这两种权限都是对包进行保护,从整体上保护一个包以避免不可信任代码的访问。其一,如果不可信任代码想要访问类的包保护成员,可能通过在被攻击的包内定义自己的新类用以获取这些成员的访问权的方式,这种方式叫包注入。针对包注入可以向package.definition属性添加需要保护的包,当检测到代码试图在包内定义新类时,类装载器的defineClass方法会抛出异常,以此达到防止包被恶意注入。可通过将包配置为RuntimePermission("defineClassInPackage."+package)给予权限。其二,为防止不可信代码对包进行访问,可通过限制包访问但同时赋予特定代码的访问权限,向package.access属性添加需要保护的包,当检测到代码试图访问上述包中的类时,类加载器的loadClass方法会抛出异常,以此达到包的访问限制。把RuntimePermission("accessClassInPackage."+package)权限赋予某个包即可实现其访问权限。

类装载器中的defineClass跟loadClass这两个方法比较奇特,如果想要深入了解可以研究JDK的类加载器的加载机制,从本书第二部分关于类加载器中知道,简单地说,每个类被加载器加载时都会调用loadClass方法,loadClass会进行如下判断:①从内存中查找此类是否已经加载,如已加载直接返回此类。②如果存在父类加载器,就委派给父类加载器加载。③如果不存在父类加载器,就尝试由启动类加载器加载。④如果以上三种方法都无法加载此类,才调用这个加载器类的findClass方法,此方法再调用defineClass方法。

在Tomcat启动过程中,当实例化Catalina类的时候(构造函数),就完成了package.definition跟package.access的安全属性设置,图3-1-5-3为SecurityConfig类图,此类通过读取catalina.properties中的属性完成设置,其中两个属性为

package.access

=sun.,org.apache.catalina.,org.apache.coyote.,org.apache.tomcat.,org.apache.jasper.

package.definition

=sun.,java.,org.apache.catalina.,org.apache.coyote.,org.apache.tomcat.,org.apache.jasper.

即以上这些包都需要进行权限检查。此类设置属性时并非直接设置,而是先读取系统已有的安全属性的值,然后再把这些包追加到后面。例如,先String access = Security.getProperty("package.access");

再Security.setProperty("package.access",access+","+"sun.,org.apache.catalina,…");

 

在Tomcat中,当启动了SecurityManager进行安全管理时,有些类是必须要使用的类,为避免由安全管理器导致运行到一半抛AccessControlException异常,在启动一开始就预先加载一些类,以此检查是否存在某些类读取的权限问题。SecurityClassLoad类负责对一些类进行预加载。

Tomcat的系统安全管理的更多相关文章

  1. Keepalived+Nginx+tomcat实现系统的高可用

    Keepalived+Nginx+tomcat实现系统的高可用 1:安装vmware虚拟机 2:安装linux系统,我自己下载的centos6.5 3:安装JDK,tomcat 解压tomcat到/u ...

  2. linux (ubuntu) 下设置 tomcat 随系统自动启动

    网上说的有很多, 我只记录一种 1. 切换到 /etc/init.d/ 目录下 2. sudo vim tomcat 3. 在打开的文件里写入以下内容 #!/bin/sh # chkconfig: # ...

  3. CentOS7+Tomcat 生产系统部署

    1 准备OS账户 安全起见,本着最小权限原则,生产系统决不同意使用root账户来执行tomcat.为此,建立新账户tomcat,并设定登录password. useradd tomcat passwd ...

  4. Tomcat Windows 系统下安装及注意事项

    1 获取Tomcat 安装包  http://tomcat.apache.org/ tar.gz 文件是Linux系统下的安装版本 exe文件是 Windows系统下的安装版本 zip 文件是Wind ...

  5. Tomcat日志系统详解

    综合:Tomcat下相关的日志文件 Cataline引擎的日志文件,文件名catalina.日期.log Tomcat下内部代码丢出的日志,文件名localhost.日期.log(jsp页面内部错误的 ...

  6. 《Tomcat日志系统详解》

    综合:Tomcat下相关的日志文件 Cataline引擎的日志文件,文件名catalina.日期.log Tomcat下内部代码丢出的日志,文件名localhost.日期.log(jsp页面内部错误的 ...

  7. CentOS7 安装tomcat为系统服务器 Systemctl管理Tomcat,并设置开机启动

    本文转载:http://blog.chinaunix.net/uid-24648266-id-5729891.html CentOS7开始,从/etc/init.d脚本改为了systemctl管理服务 ...

  8. 第11章 Tomcat的系统架构与设计模式

    11.1 Tomcat总体设计 11.1.1 Tomcat总体架构 Tomcat和核心有连个组件:Connector和Container,Connector是可以被替换的.一个container可以有 ...

  9. 【tomcat】关于tomcat的使用:将tomcat加入系统服务列表

    一.下载TOMCAT 选择合适的版本进行下载: http://tomcat.apache.org/ 解压zip文件得到tomcat目录: 二.添加CATALINA_HOME到环境变量 service. ...

随机推荐

  1. IO流大总结

    - - - - - - - - - - - - - - - 写在前面 - - - - - - - - - - - - - - - 1.概念 IO流用来处理设备之间的数据传输 Java对数据的操作是通过 ...

  2. [HNOI 2004]L语言

    Description 标点符号的出现晚于文字的出现,所以以前的语言都是没有标点的.现在你要处理的就是一段没有标点的文章. 一段文章T是由若干小写字母构成.一个单词W也是由若干小写字母构成.一个字典D ...

  3. [HNOI2001]软件开发

    题目描述 某软件公司正在规划一项n天的软件开发计划,根据开发计划第i天需要ni个软件开发人员,为了提高软件开发人员的效率,公司给软件人员提供了很多的 服务,其中一项服务就是要为每个开发人员每天提供一块 ...

  4. ●BZOJ 4361 isn

    题链: http://www.lydsy.com/JudgeOnline/problem.php?id=4361 题解: 容斥,DP,树状数组 注意题意:一旦变成了非降序列,就停止操作.即对非降序列进 ...

  5. [bzoj4922]Karp-de-Chant Number

    来自FallDream的博客,未经允许,请勿转载,谢谢. 卡常数被称为计算机算法竞赛之中最神奇的一类数字,主要特点集中于令人捉摸不透,有时候会让水平很高的选手迷之超时. 普遍认为卡常数是埃及人Qa'a ...

  6. 剖析Vue原理&实现双向绑定MVVM

    转自:http://www.w3cmark.com/2016/496.html 本文能帮你做什么? 1.了解vue的双向数据绑定原理以及核心代码模块 2.缓解好奇心的同时了解如何实现双向绑定 为了便于 ...

  7. IntelliJ IDEA光标变粗 backspace无法删除内容解决方法

    进入了vim插件 1.ctrl+alt+s快捷键打开Settings 2.选择左侧列表中的Plugins 3.在右侧面板的搜索框中搜索IdeaVim 4.将复选框中的钩子去掉 backspace成了其 ...

  8. Tomcat性能调优-JVM监控与调优

    参数设置 在Java虚拟机的参数中,有3种表示方法用"ps -ef |grep "java"命令,可以得到当前Java进程的所有启动参数和配置参数: 标准参数(-),所有 ...

  9. 继承自 DevExpress 17.2 的自定义控件如何在工具箱显示

    最近把DevExpress版本从13.1升级到了17.2,结果发现继承自DevExpress的自定义控件居然在工具箱中消失了,弄了两天还是没有任何头绪,部分自定义Dev控件可以正常出现,但大部分自定义 ...

  10. electron应用以管理员权限启动

    最近在用electron开发PC桌面应用,其中有个需求就是整个应用以管理员权限启动.很头痛,各种google,baidu. 最后终于解决了,可以分为三个步骤,做个总结分享. 一.如果没有manifes ...