1、Tomcat漏洞

       近日,Apache Tomcat 发布安全更新,更新了一处拒绝服务漏洞(CVE-2021-42340)。攻击者可以通过该漏洞进行拒绝服务攻击。建议广大用户及时升级至最新版本。

1.1、漏洞描述

       Apache Tomcat 是阿帕奇(Apache)基金会的一款轻量级 Web应用服务器。该程序实现了对 Servlet 和 JavaServer Page(JSP) 的支持。

CVE-2021-42340

       当 Tomcat WebSocket 连接关闭时,用于收集 HTTP 升级连接指标的对象没有被释放,于是造成了内存泄漏。攻击者可通过内存泄露错误进行拒绝服务攻击。

该漏洞CVSS3评分:7.5,危害等级:高危

1.2、CVE 编号

CVE-2021-42340

1.3、FOFA 查询

app="APACHE-Tomcat"

1.4、影响范围

影响版本:

Apache Tomcat 10.0.0-M10 - 10.0.11
Apache Tomcat 10.1.0-M1 - 10.1.0-M5
Apache Tomcat 9.0.40 - 9.0.53
Apache Tomcat 8.5.60 - 8.5.71

修复版本:

Apache Tomcat 10.0.12
Apache Tomcat 10.1.0-M6
Apache Tomcat 9.0.54
Apache Tomcat 8.5.72

参考:【安全通报】Apache Tomcat 拒绝服务漏洞(CVE-2021-42340)|NOSEC安全讯息平台 - 白帽汇安全研究院

2、查看当前使用的Tomcat版本号

2.1、Maven Repository中查看

比如我们需要查Spring Boot  2.3.12.RELEASE 的内嵌Tomcat版本, 可以打开链接:

https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-parent/2.3.12.RELEASE

如下图, 红框标记的就是tomcat的版本。

 

2.2、查看dependepency

透过IDE

目前大家主要使用IDEA来进行开发,下面是IDEA查看Tomcat的版本:

透过命令行

Gradle可以采用以下命令打印依赖项:

./gradlew dependencies

数据结果示例:

...
|    +--- org.springframework.boot:spring-boot-starter-tomcat:2.1.0.RELEASE
|    |    +--- javax.annotation:javax.annotation-api:1.3.2
|    |    +--- org.apache.tomcat.embed:tomcat-embed-core:9.0.12
|    |    +--- org.apache.tomcat.embed:tomcat-embed-el:9.0.12
|    |    \--- org.apache.tomcat.embed:tomcat-embed-websocket:9.0.12
|    |         \--- org.apache.tomcat.embed:tomcat-embed-core:9.0.12
...

Maven可以采用以下命令打印依赖项:  

mvn dependency:tree > output.txt   # 输出到文件里

3、指定SpringBoot项目内嵌的Tomcat版本

3.1、直接升级SpringBoot的版本

        因为SpringBoot内嵌的Tomcat会伴随SpringBoot的升级而升级,所以可以根据需要选择合适的Tomcat版本,这种特别需要升级Tomcat版本时使用,当然还是要根据情况,因为升级SpringBoot的版本也是有成本的。

3.2、排除SpringBoot的Tomcat,指定Tomcat版本

        有时候我们需要在特定情况下使用特定的Tomcat版本,这时候总不能因为Tomcat就改变SpringBoot的版本,所以可以采用排除SpringBoot中的Tomcat包,然后手动指定Tomcat的版本,当然还要引入Tomcat相关的包。

Gradle的配置:

compile('org.springframework.boot:spring-boot-starter-web') {
    exclude module: "spring-boot-starter-tomcat"
}
compile 'org.apache.tomcat.embed:tomcat-embed-core:+'
compile 'org.apache.tomcat.embed:tomcat-embed-el:+'
compile 'org.apache.tomcat.embed:tomcat-embed-logging-juli:+'
compile 'org.apache.tomcat.embed:tomcat-embed-websocket:+'

如果不指定版本,则会使用最新的Tomcat版本, 否则直接指定对应的版本号。

Maven的配置:

若引入spring-boot的方式为加入<parent>:

<!-- Inherit defaults from Spring Boot -->
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.3.12.RELEASE</version>
</parent>

则只需在properties中指定tomcat版本即可,在 pom.xml文件里面添加一个标签<properties>,添加期望的版本。其实这个配置就是指定tomcat版本。

<properties>
    <tomcat.version>9.0.54</tomcat.version>
</properties>

添加必要的Jar包:

<dependency> 
   <groupId>org.apache.tomcat</groupId> 
   <artifactId>tomcat-juli</artifactId> 
   <version>${tomcat.version}</version> 
 </dependency>
<dependency>
    <groupId>org.apache.tomcat.embed</groupId>
    <artifactId>tomcat-embed-logging-juli</artifactId>
    <version>${tomcat.version}</version>
</dependency>

4、springboot启动看Tomcat版本号

    到这里基本就结束了,springboot启动会看到Tomcat的版本号:

3.3 升级包含多个模块的项目

      升级多模块的项目的tomcat版本,子模块依赖tomcat,但是子模块的父项目不可能是org.springframework.boot,而是项目对应的父模块,此时第一种方法就不见效了。那我们粗暴的,先将tomcat依赖剔除,再引入对应版本的tomcat版本不就行了嘛。因为tomcat相关的依赖再spring-boot-starter-web依赖模块下面,所以先将它内部包含的tomcat依赖剔除,再引入对应的tomcat版本,具体如下:

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-tomcat</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.apache.tomcat.embed</groupId>
                    <artifactId>tomcat-embed-core</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.apache.tomcat.embed</groupId>
                    <artifactId>tomcat-embed-el</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.apache.tomcat.embed</groupId>
                    <artifactId>tomcat-embed-websocket</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.apache.tomcat</groupId>
                    <artifactId>tomcat-annotations-api</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-core</artifactId>
            <version>${tomcat.version}</version>
            <exclusions>
                <exclusion>
                    <groupId>org.apache.tomcat</groupId>
                    <artifactId>tomcat-annotations-api</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.apache.tomcat</groupId>
            <artifactId>tomcat-annotations-api</artifactId>
            <version>${tomcat.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-el</artifactId>
            <version>${tomcat.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-websocket</artifactId>
            <version>${tomcat.version}</version>
            <exclusions>
                <exclusion>
                    <groupId>org.apache.tomcat.embed</groupId>
                    <artifactId>tomcat-embed-core</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

5、其他方式

修改內置的默認版本

即在 pom.xml 文件裏面添加一個標籤<properties>,添加指望的版本<tomcat.version>8.0.30</tomcat.version>
如何知道修改是否成功?
修改爲<tomcat.version>8.0.30</tomcat.version>
啓動信息:

2018-03-15 00:46:26.275  INFO 47112 --- [           main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat initialized with port(s): 8080 (http)
2018-03-15 00:46:26.282  INFO 47112 --- [           main] o.apache.catalina.core.StandardService   : Starting service Tomcat
2018-03-15 00:46:26.283  INFO 47112 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet Engine: Apache Tomcat/8.0.30
2018-03-15 00:46:26.333  INFO 47112 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2018-03-15 00:46:26.333  INFO 47112 --- [ost-startStop-1] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 1000 ms

可是,有時候啓動會報錯:

Caused by: java.lang.NoClassDefFoundError: org/apache/juli/logging/LogFactory 
  at org.apache.catalina.util.LifecycleBase.<clinit>(LifecycleBase.java:37) 
  at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory.getEmbeddedServletContainer(TomcatEmbeddedServletContainerFactory.java:169) 
  at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.createEmbeddedServletContainer(EmbeddedWebApplicationContext.java:164) 
  at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.onRefresh(EmbeddedWebApplicationContext.java:134) 
  ... 13 common frames omitted

顯然是缺乏 jar 包,在 dependency 裏面添加如下二者之一便可:

<dependency> 
   <groupId>org.apache.tomcat</groupId> 
   <artifactId>tomcat-juli</artifactId> 
   <version>${tomcat.version}</version> 
 </dependency>

      若是項目是以war包形式打包部署,即pom標籤是war,則推薦使用上面這個。

      若是項目是使用內嵌Tomcat servlet容器形式打包部署,推薦使用下面這個,其groupId和artifactId皆是embed類型的jar包。

<dependency>
    <groupId>org.apache.tomcat.embed</groupId>
    <artifactId>tomcat-embed-logging-juli</artifactId>
    <version>${tomcat.version}</version>
</dependency>

可是,還有一個問題:
spring-boot-starter-web是包含spring-boot-starter-tomcat的,查看 pom 文件可知。
也就是說,咱們沒有必要重複添加spring-boot-starter-tomcat,一個spring-boot-starter-web就能夠把一個典型的 spring web 項目搭建成功,也方便 jar 包的管理,此時須要額外添加Tomcat的GA:

<properties>
	<tomcat.version>8.0.30</tomcat.version>
</properties>
<!-- 顯式指定Tomcat版本 -->
<dependency>
   <groupId>org.apache.tomcat.embed</groupId>
    <artifactId>tomcat-embed-core</artifactId>
    <version>${tomcat.version}</version>
</dependency>

参考:

【安全通报】Apache Tomcat 拒绝服务漏洞(CVE-2021-42340)|NOSEC安全讯息平台 - 白帽汇安全研究院

查看和指定SpringBoot内嵌Tomcat的版本 - 简书

springboot:修改內置tomcat版本 - 菜鳥學院

spring-boot 替换内嵌tomcat版本 | $t/^Cipher's Blog_?\n

https://www.cxyzjd.com/article/qq_35033270/104734756

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐