如何控制War包访问Tomcat的内部实现类
Tomcat默认部署了Manager应用作为Web控制台,提供对Tomcat的管理功能。
具体功能包括但不限于:
从这些功能看,Manager能够获知Tomcat内部信息,并对Tomcat内部数据结构进行操控。这些特权功能,对Tomcat来说还是很危险的。
?
Manager应用的Servlet代码位于catalina.jar中,属于Tomcat内部实现类的一部分,我们先看看其实现机制。(本文的代码基于Tomcat 7.0.5版本)
?
Manager的实现机制Tomcat提供了一个特殊的Servlet接口类,名为 org.apache.catalina.ContainerServlet,实现该接口的Servlet可以访问Tomcat内部功能。像 Manager应用中的org.apache.catalina.manager.ManagerSerlvet类,就实现了该接口。
Tomcat启动时,会从配置文件$CATALINA_HOME/conf /catalina.properties中读取package.access属性值,然后安全属性package.access。
从注释可以看出,这是给Manager应用的session展示功能赋予必须的包访问权限。
?
在Manager应用中,负责展示session信息的不是catalina.jar中的Servlet,而是$CATALINA_HOME/webapps/manager/下的JSP文件。这些JSP文件是WebappClassLoader加载的,它们的accessClassInPackage权限会得到检查。为了通过检查,Tomcat就在安全策略文件中给他们赋予必要的包访问权限。
?
禁止普通War包调用System.exit方法如果启用了Java Security Manager,System.exit方法会要求调用者拥有exitVM权限。但是Tomcat的安全策略文件显然没有将该权限赋予普通War包。因此,普通War包如果调用System.exit方法,就会抛出异常。
?
总结对于组件容器,Java安全机制是必不可少的,特别是在生产环境中。也许,某个计划离职的程序员在Serlvet写下如此给力的代码:
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");Date date2012 = sdf.parse("2012-01-01 00:00:00");Date now = new Date();if (now.after(date2012)){ System.exit(2012);}到了2012,老板就了