`
jarfield
  • 浏览: 202689 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

如何控制War包访问Tomcat的内部实现类

阅读更多

Tomcat默认部署了Manager应用作为Web控制台,提供对Tomcat的管理功能。

具体功能包括但不限于:

  • 列出已部署的WebApp
  • 部署、卸载、启动、停止指定的WebApp
  • 展现线程池的详情,例如活动线程数、最大线程数、最小线程数等
  • 展现请求处理的统计信息,例如平均请求处理时间、请求次数、出错次数等
  • ...

从这些功能看,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类,就实现了该接口。

public class ManagerServlet extends HttpServlet implements ContainerServlet {
    // ...
} 

Container接口的代码如下:

package org.apache.catalina;
/**
 * A ContainerServlet is a servlet that has access to Catalina
 * internal functionality, and is loaded from the Catalina class loader
 * instead of the web application class loader.  The property setter
 * methods must be called by the container whenever a new instance of
 * this servlet is put into service.
 */
public interface ContainerServlet {
    /**
     * Return the Wrapper with which this Servlet is associated.
     */
    public Wrapper getWrapper();

    /**
     * Set the Wrapper with which this Servlet is associated.
     */
    public void setWrapper(Wrapper wrapper);
}

对于实现了ContainerServlet接口的Servlet,Tomcat调用其service方法前,都会调用setWrapper方法将Wrapper对象注入到Servlet实例中。

public synchronized Servlet loadServlet() throws ServletException {
    // Special handling for ContainerServlet instances
    if ((servlet instanceof ContainerServlet) &&
         (isContainerProvidedServlet(servletClass) ||
           ((Context)getParent()).getPrivileged() )) {
                ((ContainerServlet) servlet).setWrapper(this);
    }
}

 

通过Wrapper对象,Servlet可以获得相关的Context对象、Host对象、Engine对象、MbeanServer对象等等。有了这些对象,就可以获知Tomcat内部的信息及其它对象,并且对Tomcat进行管理。

 

可见,虽然Manager应用属于Tomcat内部实现类,但是尽量与Tomcat内部核心代码隔离。因此才会有ContainerServlet这样的接口。

 

普通War包禁止使用ContainerServlet

如果普通War包也能实现ContainerServlet接口,进而拥有与Manager应用相同的能力,那么就是一个极大的安全隐患。

 

上面这段代码中,isContainerProvidedServlet方法会判断要加载的Serlvet,是否是Tomcat提供的Servlet。如果不是,就不会调用setWrapper方法。这样,Servlet也不会获得特权功能。

/**
 * Return <code>true</code> if the specified class name represents a
 * container provided servlet class that should be loaded by the
 * server class loader.
 *
 * @param classname Name of the class to be checked
 */
protected boolean isContainerProvidedServlet(String classname) {

    if (classname.startsWith("org.apache.catalina.")) {
        return (true);
    }
    try {
        Class<?> clazz = this.getClass().getClassLoader().loadClass(classname);
        return (ContainerServlet.class.isAssignableFrom(clazz));
    } catch (Throwable t) {
        ExceptionUtils.handleThrowable(t);
            return (false);
    }

}

 类名必须以org.apache.catalina开头,必须是ServerClassLoder加载的Servlet,才认为是Tomcat内部提供的Servlet。

 

普通War是不能满足这个条件的,因为其Servlet必然是WebappClassLoader加载的,而不是ServerClassLoder。

 

这里体现了JVM的一个安全机制:通过不同的类加载器来隔离信任的类和不信任的类。

禁止普通War包直接访问Tomcat内部实现类

虽然普通War包不能借助ContainerServlet来操纵Tomcat内部,但是如果它直接访问Tomcat内部的一些类,特别是静态对象,也可能破坏Tomcat的内部状态。

 

理论上说,最好禁止组件访问容器的内部实现类。因为组件可以使用任意代码,甚至像System.exit(0);这样的停机代码。

 

从版本6开始,Tomcat简化了类加载器层次,Tomcat的内部实现类是WebApp是可见的。因此,普通War包中的Servlet可以访问Tomcat任何内部实现类。

 

不过呢,我们可以通过Java Security Manager机制 ,限制普通War包可以访问哪些内部实现类,不可以访问哪些内部实现类。前提是,Tomcat必须启用Java Security Manager机制。

sh $CATALINA_HOME/bin/startup.sh -security    (Unix)

 

Java Security Manager机制的主要原理

Java Security Manager机制,利用java.lang.SecurityManager对象和安全策略,对方法调用者进行权限检查。如果没有权限,就抛出异常。

 

针对访问某个package内的代码,Java Security Manager机制提供了一种权限保护方法:

  1. 设置安全属性package.access,可以指定哪些包需要受到权限保护。
  2. SecurityManager类的checkPackageAccess方法,可以检查packege的访问者是否具有accessClassInPackage权限。如果没有,则抛出异常。

下面是一段示例代码:

import java.security.Security;

//指定org.apache.catalina包受到权限保护
String PACKAGE_ACCESS = "org.apache.catalina.";
Security.setProperty("package.access", PACKAGE_ACCESS);

//没有accessClassInPackage.org.apache.catalina的调用者会被拒绝。
System.getSecurityManager().checkPackageAccess("org.apache.catalina"); 

 

WebApp的类都通过org.apache.catalina.loader.WebappClassLoader加载的,该类加载器的loadClass方法会调用者的accessClassInPackage权限。

public synchronized Class<?> loadClass(String name, boolean resolve)
        throws ClassNotFoundException {
    // ...

    // (0.5) Permission to access this class when using a SecurityManager
    if (securityManager != null) {
        int i = name.lastIndexOf('.');
        if (i >= 0) {
            try {
                securityManager.checkPackageAccess(name.substring(0,i));
            } catch (SecurityException se) {
                String error = "Security Violation, attempt to use " +
                    "Restricted Class: " + name;
                log.info(error, se);
                throw new ClassNotFoundException(error, se);
            }
        }
    }

    //...
}

Tomcat启动时,会从配置文件$CATALINA_HOME/conf /catalina.properties中读取package.access属性值,然后安全属性package.access。

package.access=sun.,org.apache.catalina.,org.apache.coyote.,org.apache.tomcat.,org.apache.jasper.,sun.beans.

可见,Tomcat的内部实现类,和SUN JDK的内部实现类,基本都得到了保护。

 

如果War包没有这些package的accessClassInPackage权限,自然就不能访问Tomcat的内部类。默认情况下,War包均没有上述package的accessClassInPackage权限,因此无法访问Tomat的内部实现类。

 

那么Tomcat启用了Java Security Manager,Manager应用中的ManagerServlet,为什么还可以访问Tomcat内部实现呢?

 

这是因为,ManagerServlet位于catalina.jar中,是由ServerClassLoader加载的。ServerClassLoader不会调用securityManager.checkPackageAccess()方法来检查accessClassInPackage权限。

 

Tomcat的安全策略文件

那么,War包默认拥有哪些权限呢?我们可以查看Tomat的安全策略文件。默认情况下,Tomcat使用 $CATALINA_HOME/conf/catalina.policy作为安全策略文件。其中有一段权限规则比较有意思。

// The Manager application needs access to the following packages to support the
// session display functionality
 grant codeBase "file:${catalina.base}/webapps/manager/-" {
     permission java.lang.RuntimePermission "accessClassInPackage.org.apache.catalina";
     permission java.lang.RuntimePermission "accessClassInPackage.org.apache.catalina.manager";
     permission java.lang.RuntimePermission "accessClassInPackage.org.apache.catalina.manager.util";
};

从注释可以看出,这是给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,老板就囧了

分享到:
评论
1 楼 tonghaoqi__ 2015-04-15  
必须点赞。。

相关推荐

    jenkins war包

    Jenkins的WAR包内部包含以下几个关键部分: - `WEB-INF` 目录:存放Jenkins的核心类和库,包括`classes`子目录(包含编译后的Java类)和`lib`子目录(包含所有依赖的JAR文件)。 - `META-INF` 目录:包含关于WAR...

    jpress4.2.0源码和war包 + 留言插件 + 安装说明

    **JPress 4.2.0 源码与WAR包详解** JPress是一款基于Java技术的开源内容管理系统,特别适合个人博客、企业网站或新闻资讯类网站的建设。其4.2.0版本提供了丰富的功能和优化,使得网站管理更为便捷。本篇文章将详细...

    tomcat6的源码

    `Realm`接口及其实现类(如`MemoryRealm`, `JDBCRealm`)处理用户身份验证,`AccessController`处理访问控制。 10. **错误处理**:当发生错误时,Tomcat会生成定制的错误页面。源码中,`ErrorReportValve`类处理...

    apache-tomcat-7.0.27-windows-x86.zip

    6. **webapps** 目录:这是默认的应用程序部署目录,任何放置在此目录下的WAR文件或已展开的目录会被Tomcat自动部署为Web应用程序。 7. **work** 目录:包含Tomcat处理JSP文件时生成的编译后类文件和应用的临时工作...

    tomcat7源码环境搭建

    1. **Servlet和JSP规范**:Tomcat是Servlet和JSP规范的实现,了解这两者的工作原理对于理解Tomcat的内部流程至关重要。 2. **HTTP服务器架构**:Tomcat作为HTTP服务器,其请求处理流程、线程模型、连接器...

    apache-tomcat-9.0.65-windows-x64.zip

    - **安全性**:Tomcat支持多种安全特性,如SSL/TLS加密、角色基础的访问控制以及与Java Authentication and Authorization Service (JAAS)的集成。 - **性能优化**:可以通过调整配置参数,如线程池大小、连接超时...

    纯净的 tomcat 8包

    **纯净的 Tomcat 8 包详解** Tomcat 是一个开源的、基于 Java 的应用服务器,主要用于部署和运行 Java Servlet 和 JavaServer Pages (JSP) 应用程序。它的设计简单而高效,使得开发者能够快速地开发和部署 Web 应用...

    tomcat的安装配置

    2. **放置WAR包至Tomcat** - 将导出的WAR文件放置到Tomcat的`webapps`目录下。 - 当Tomcat启动时,会自动解压WAR文件并创建对应的Web应用程序目录结构。 3. **启动Tomcat服务** - 进入Tomcat安装目录下的`bin`...

    TOMCAT8.0.36

    Tomcat 8.0.36提供了一些安全特性,如SSL支持、角色基础的访问控制等。配置`conf/server.xml`中的`&lt;Connector&gt;`元素来启用SSL,使用`&lt;Realm&gt;`元素进行用户认证,以及通过`&lt;Security-constraint&gt;`和`&lt;Role&gt;`元素定义...

    nexus.war.zip

    此外,它也可以用于控制访问权限,确保只有授权的用户或服务才能访问某些私有的、内部的软件构件。 将“nexus.war”部署到Tomcat服务器意味着,Tomcat将解析这个WAR文件并运行其中的Java Web应用,提供Nexus的服务...

    深入剖析Tomcat+源码.zip

    《How Tomcat Works》是了解Tomcat内部机制的重要参考书籍,通过此书,读者可以了解到Tomcat如何处理HTTP请求,如何管理Web应用程序,以及它是如何实现高效的并发性能的。书中详细解释了Tomcat的核心组件,包括...

    ApacheTomcat自动WAR部署和pwning渗透测试工具。_Python_下载.zip

    通过这样的工具,你可以快速地将更新的WAR文件推送到Tomcat服务器,实现快速迭代和调试。Python是一种流行的编程语言,常用于开发各种自动化工具,包括与服务器管理相关的工具。 渗透测试,或称为“pwn”(源自黑客...

    apache-tomcat-7.0.108.tar.gz

    Apache Tomcat是一个开源的Java Servlet容器,主要用于实现JavaServer Pages (JSP)、Java Servlet以及Java EE的Web应用程序。在本例中,我们讨论的是Apache Tomcat 7.0.108版本的tar.gz压缩文件。这个版本是Tomcat 7...

    tomcat6 源代码

    Tomcat提供了多种安全机制,如SSL/TLS加密,角色基础的访问控制(RBAC),以及基于Jaas的身份验证和授权。这些可以通过`conf/server.xml`和`conf/tomcat-users.xml`等配置文件进行设置。 8. **性能优化**: ...

    Tomcat5启动流程与配置详解 .

    - `naming-common.jar`: JNDI接口实现类,Tomcat使用这些类在内存中使用`Context`。 - `naming-resources.jar`: JNDI实现,Tomcat使用它们定位Web应用的静态资源。 - `servlet.jar`: Servlet和JSP API。 - `...

    apache-tomcat-8.0.44

    3. **限制访问**:通过防火墙或服务器配置,只允许特定IP访问Tomcat管理界面。 **七、总结** `apache-tomcat-8.0.44`是一个强大且可靠的Java Web服务器,提供高效的服务和丰富的功能。无论是初学者还是经验丰富的...

    droos6.4.0在tomcat布署时的缺失包-完整

    - 创建一个WAR文件,包含所有必要的依赖,然后将该WAR文件部署到Tomcat。 在打包过程中,务必避免重复的类(由于不同的依赖版本冲突),这可能导致Classpath问题。使用Maven的`dependency:tree`命令或者Gradle的`...

    apache-tomcat-v8.0.41

    Apache Tomcat v8.0.41 是一个广泛使用的开源软件,它是一个实现了Java Servlet和JavaServer Pages(JSP)规范的应用服务器,主要用于部署和运行Java Web应用程序。Tomcat是Apache软件基金会的Jakarta项目的一部分,...

    官方原版tomcat8.5.13 64位

    Apache Tomcat 8.5.13 是一个广泛使用的开源软件,它是一个符合Java Servlet和JavaServer Pages(JSP)规范的应用服务器,主要用于部署和运行Java Web应用程序。这个版本是针对64位操作系统设计的,这意味着它可以在...

    Tomcat6源码下载

    7. **安全配置**:Tomcat提供了全面的安全管理机制,包括角色认证、访问控制、SSL/TLS加密等,这些配置都在server.xml等配置文件中定义。 8. **部署与热更新**:Tomcat支持WAR文件部署和热更新,使得开发者能够在不...

Global site tag (gtag.js) - Google Analytics