tomcat安全

安装部署

1、安装包应该从官网下载,确保发布的安全性。下载后使用md5/PGP校验完整性。这里使用sha512sum验证,因为gpg那个没找到.asc文件下载地址

[root@iZzm446eh1ux98Z packages]# curl https://downloads.apache.org/tomcat/tomcat-8/v8.5.57/bin/apache-tomcat-8.5.57.tar.gz.sha512
720de36bb3e40a4c67bdf0137b12ae0fd733aef772d81a4b8dab00f29924ddd17ecb2a7217b9551fc0ca51bd81d1da13ad63b6694c445e5c0e42dfa7f279ede1 *apache-tomcat-8.5.57.tar.gz


[root@iZzm446eh1ux98Z packages]# sha512sum apache-tomcat-8.5.57.tar.gz
720de36bb3e40a4c67bdf0137b12ae0fd733aef772d81a4b8dab00f29924ddd17ecb2a7217b9551fc0ca51bd81d1da13ad63b6694c445e5c0e42dfa7f279ede1  apache-tomcat-8.5.57.tar.gz

2、删除不必要应用

Tomcat安装之后,自带了一些web应用,这些应用是不必要的,应该尽量移除。其中webapps下的docs、examples、ROOT可以直接移除。

host-manager和manager是管理和监控的包,一般有第三方工具替代,也可以移除。如果需要使用这两个包,可以配置RemoteAddrValve增加对他们的访问控制(在webapps/host-manager/META-INF/context.xml),8.5版本前需要手动开启,8.5版本之后默认开启只有本机可以访问。

[test@mysql META-INF]$ cat context.xml 
<Context antiResourceLocking="false" privileged="true" >
  <Valve className="org.apache.catalina.valves.RemoteAddrValve"
         allow="127.d+.d+.d+|::1|0:0:0:0:0:0:0:1" />

host-manager和manager只有在conf/tomcat-users.xml中添加了用户信息才可以正常访问,但是为了避免被攻击,还应该设置足够健壮的密码。还需要确保conf/server.xml中配置了org.apache.catalina.realm.LockOutRealm,防止攻击者进行暴力破解

3、避免使用root用户启动Tomcat,应该单独为Tomcat服务器建立一个用户,授予运行服务器所需的最小权限。比如Tomcat用户不能登录系统。

[root@iZzm446eh1ux98Z webapps]# useradd -s /sbin/nologin -M tomcat

[root@iZzm446eh1ux98Z webapps]# chown -R tomcat.tomcat /opt/softwares/apache-tomcat-8.5.57/

server.xml配置

1、移除不必要的组件

server.xml中配置了两个链接器,HTTP链接器(8080)和AJP链接器(8009)。一般只需要保留一个即可:当Tomcat独立启动,并且不存在前置web服务器时,可以删除AJP链接器而保留HTTP链接器。否则,可以删除HTTP链接器而保留AJP链接器

如果不需要使用host-manager和manager管理,那么可以删除<Engine>下<Realm>和名为"UserDatabase"的resourceName

      <!--Realm className="org.apache.catalina.realm.LockOutRealm"-->
        <!-- This Realm uses the UserDatabase configured in the global JNDI
             resources under the key "UserDatabase".  Any edits
             that are performed against this UserDatabase are immediately
             available for use by the Realm.  -->
        <!--Realm className="org.apache.catalina.realm.UserDatabaseRealm"
               resourceName="UserDatabase" -->

如果对tomcat配置足够了解,可以删除server.xml中的注释

2、配置更改

2.1  关闭shutdown端口

1、关闭SHUTDOWN

Tomcat默认配置的shutdown端口为8005,发送指令为"SHUTDOWN",所以只要对8005端口发送"SHUTDOWN"指令,Tomcat就会关闭。如果禁用此功能,可以将port属性设置为 -1。此时,只能使用kill等工具关闭Tomcat

如果需要使用此功能,可以将port改为其他未占用端口,同时设置指令为复杂指令。

<Server port="8005" shutdown="abcd">

测试

[test@mysql conf]$ telnet localhost 8005
Trying ::1...
telnet: connect to address ::1: Connection refused
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
abcd
Connection closed by foreign host.

tomcat禁用8005端口后,使用shutdown.sh脚本报错 "SEVERE: No shutdown port configured. Shut down server through OS signal. Server not shut down.",报错原因是因为:

禁用关闭命令端口在tomcat以windows服务或linux等系统的jsvc方式启动时可以生效,在标准shell脚本启动的方式下不会生效,这将阻止shutdown和catalina脚本停止tomcat

jsvc方式启动tomcat可以参考:https://www.cnblogs.com/zh-dream/p/13605029.html

2.2  Tomcat链接器的重要安全属性应当关注,如下表所示:

属性 描述 默认值
address 该属性用于控制连接器监听的IP地址,默认情况下连接器监听服务器配置的所有IP地址  
allowTrace 是否开启HTTP的trace方法,多用于DEBUG,在默写浏览器可能会导致安全问题,默认禁用  
maxPostSize

FROM URL参数转换处理的POST请求的最大字节数,负值或小于0,表示不做限制

注意:tomcat7.0.63之前是0或负值才表示不作限制,否则post请求失败

由于转换参数在请求处理过程中会被缓存,因此设置合适的上限有助于减少DOS攻击

2MB
maxSavePostSize

FROM或者CLIENT-CERT认证时,保存或者缓冲的POST请求最大字节数。

由于参数在认证过程中会被缓存,因此设置合适的上限有助于减少DOS攻击

2MB
maxParameterCount 自动转换的参数(GET和Post之和)最大个数,超出该值时将被忽略。负值,不做限制,需要根据实际情况进行设置
注意:FailedRequestFilter过滤器可用于拒绝超出该限制的请求
10000
xpoweredBy 设置为true,tomcat会为响应添加X-Powered-By头信息,这会使攻击者很容易识别服务器类型及版本并据此发送针对性攻击。 false
server

控制"Server"HTTP头内容,默认为"Apache-Coyoto/1.1"。

攻击者很容易据此识别服务器类型并发动针对性攻击,建议在生成环境改成其他值

 

默认情况下,server.xml只配置了名为localhost的Host,并且是自动部署的,web应用目录为$CATALINA_BASE/webapps。所以webapps目录下的目录或者WAR包都在Tomcat启动时自动部署,包括被植入的恶意应用。有两种解决办法:

a、修改web应用的部署目录为其他路径,使攻击者找不到正确的部署目录

b、禁用自动部署,将Host的autoDeploy和deployOnStartup属性设置为false,这时只有在<Host>下配置的<Context>子元素才会被部署,而且变更web应用的类文件时,需要手动重启服务。除此之外,可以将Host的deployXML设置为false,此时Tomcat将忽略web应用META-INF目录下的context.xml

2.3  <Context>元素的属性也和服务器安全密切相关:

属性 描述 默认值
crossContext 用于控制是否可以访问其他Contex资源,除非是可信任的web应用,否则不要开启 false
privileged 用于控制是否可以使用容器提供的Servlet,除非是可信任的web应用,否则不要开启 false
allowLinking 是否允许使用符号链接,如果在大小写敏感的操作系统开启该属性将会导致禁用一些安全措施,且允许直接访问WEB-INF目录 false
sessionCookiePathUsesTrailingSlash

用于解决IE、Safari、Edge等浏览器的BUG,防止当多个应用共享通用的路径前缀时,会话Cookie跨应用暴露。

开启该属性时,会存在Servlet映射路径为/*的情况。最好的方式是避免供应用共享路径前缀

false

2.4  错误页的处理

web应用异常有ErrorReportValve处理,这会输出Tomcat版本信息,还会将异常栈显示给用户,导致泄漏系统信息。在生产环境中,应该尽量避免。

首先,可以在web.xml中添加<error-page>,定制化错误页面,也可以提高客户体验。也可以定制化ErrorReportValve(将属性showServerInfo设置为false隐藏服务器的信息,将属性showReport设置false隐藏异常栈信息

2.5 其他影响安全的属性

属性 影响 默认值
org.apache.catalina.connector.RECYCLE_FACADES

控制每次请求是否重建Connector外观类,

设置为true时,每次请求都会重建外观类和请求参数映射;

设置为false,tomcat会复用外观类和请求参数映射,这样会增加由于系统缺陷导致将错误数据继续向后续请求传递

false
org.apache.catalina.connector.CoyoteAdapter.ALLOW_BACKSLASH 允许请求URL的非标准转换,解决URL中包含%5C的问题 false
org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH

允许请求URL的非标准转换,解决URL中包含%2F的问题

如果这两个参数使用,攻击者可能会绕过前置代理增加的安全约束,导致安全问题

false
org.apache.catalina.connector.Response.ENFORCE_ENCODING_IN_GET_ERITER

用于控制GET请求响应是否强制编码,不指定时默认为(ISO-8859-1)

许多浏览器在响应使用默认编码会违反RFC2616,尝试猜测响应编码,这时虽然兼容了,但是会导致安全风险(XSS)

true,强制编码

对于DefaultServlet,需要设置readonly为true,否则将允许客户端删除或修改服务器上的静态资源以及上传新的资源。

listings参数也需要设置为false,如果设置为true,可能会泄漏应用目录信息,而且容易导致DOS攻击(尤其目录非常多时,会显著增加CPU使用率)。

showServerInfo参数设置为false,避免listings目录时输出Tomcat版本信息

[test@mysql apache-tomcat-8.5.6]$ vim conf/web.xml 
    <servlet>
        <servlet-name>default</servlet-name>
        <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
        <init-param>
            <param-name>debug</param-name>
            <param-value>0</param-value>
        </init-param>
        <init-param>
            <param-name>listings</param-name>
            <param-value>false</param-value>
        </init-param>
        <init-param>
            <param-name>readonly</param-name>
            <param-value>true</param-value>
        </init-param>
        <init-param>
            <param-name>showServerInfo</param-name>
            <param-value>false</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

访问测试

 当改为true时,访问测试

        <init-param>
            <param-name>listings</param-name>
            <param-value>true</param-value>
        </init-param>
        <init-param>
            <param-name>readonly</param-name>
            <param-value>true</param-value>
        </init-param>

隐藏Tomcat版本信息

[root@iZzm446eh1ux98Z apache-tomcat-8.5.57]# vim conf/web.xml

    <servlet>
        <servlet-name>default</servlet-name>
        <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
        <init-param>
            <param-name>debug</param-name>
            <param-value>0</param-value>
        </init-param>
        <init-param>
            <param-name>showServerInfo</param-name>
            <param-value>false</param-value>
        </init-param>
        <init-param>
            <param-name>readonly</param-name>
            <param-value>true</param-value>
        </init-param>
        <init-param>
            <param-name>listings</param-name>
            <param-value>false</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

 上面的配置好像不太好用,建议用下面的方法:

# bin/version.sh 
Using CATALINA_BASE:   /opt/softwares/apache-tomcat-8.5.6
Using CATALINA_HOME:   /opt/softwares/apache-tomcat-8.5.6
Using CATALINA_TMPDIR: /opt/softwares/apache-tomcat-8.5.6/temp
Using JRE_HOME:        /opt/softwares/jdk1.8.0_191
Using CLASSPATH:       /opt/softwares/apache-tomcat-8.5.6/bin/bootstrap.jar:/opt/softwares/apache-tomcat-8.5.6/bin/tomcat-juli.jar
Server version: Apache Tomcat/8.5.6
Server built:   Oct 6 2016 20:15:31 UTC
Server number:  8.5.6.0
OS Name:        Linux
OS Version:     3.10.0-862.el7.x86_64
Architecture:   amd64
JVM Version:    1.8.0_191-b12
JVM Vendor:     Oracle Corporation
进入CATALINA_BASE的lib目录

[test@mysql lib]$ unzip catalina.jar 

[test@mysql lib]$ cd org/apache/catalina/util/

[test@mysql util]$ vim ServerInfo.properties 

server.info=Fk.U
server.number=v0.1
server.built=1979:01:01 00:00:01 UTC


[test@mysql lib]$ jar  uvf catalina.jar org/apache/catalina/util/ServerInfo.properties

重启Tomcat,查看信息

[test@mysql lib]$ ../bin/startup.sh 
Using CATALINA_BASE:   /home/test/softwares/apache-tomcat-8.5.6
Using CATALINA_HOME:   /home/test/softwares/apache-tomcat-8.5.6
Using CATALINA_TMPDIR: /home/test/softwares/apache-tomcat-8.5.6/temp
Using JRE_HOME:        /home/test/softwares/jdk1.8.0_191
Using CLASSPATH:       /home/test/softwares/apache-tomcat-8.5.6/bin/bootstrap.jar:/home/test/softwares/apache-tomcat-8.5.6/bin/tomcat-juli.jar
Tomcat started.


[test@mysql lib]$ ../bin/version.sh 
Using CATALINA_BASE:   /home/test/softwares/apache-tomcat-8.5.6
Using CATALINA_HOME:   /home/test/softwares/apache-tomcat-8.5.6
Using CATALINA_TMPDIR: /home/test/softwares/apache-tomcat-8.5.6/temp
Using JRE_HOME:        /home/test/softwares/jdk1.8.0_191
Using CLASSPATH:       /home/test/softwares/apache-tomcat-8.5.6/bin/bootstrap.jar:/home/test/softwares/apache-tomcat-8.5.6/bin/tomcat-juli.jar
Server version: Fk.U
Server built:   1979:01:01 00:00:01 UTC
Server number:  v0.1
OS Name:        Linux
OS Version:     5.12.9-1.el7.x86_64
Architecture:   amd64
JVM Version:    1.8.0_191-b12
JVM Vendor:     Oracle Corporation

关闭websocket

如果web应用不使用Websocket,可以使用如下配置禁用

<Context containerSciFilter="org.apache.tomcat.websocket.server.WsSci">
</Context>

 Tomcat安全漏洞

CVE-2021-24122漏洞:根据分析,当Tomcat部署在Windows系统的场景中,该漏洞源于JRE API File.getCanonicalPath() 与 Windows API (FindFirstFileW)行为不一致,Tomcat使用NTFS文件系统从网络位置提供资源时,存在未授权查看JSP源代码的漏洞,导致信息泄露效果,恶意攻击者可以利用该漏洞获得目标系统敏感信息后进一步实施攻击。
影响范围:8.5.0 - 8.5.59
危险级别:高危

CVE-2020-17527漏洞:该漏洞会导致在一个HTTP/2的连接过程中,相连的后续请求中,可重新使用来自上一个HTTP请求头中的值。这可能会导致错误并关闭HTTP/2连接,会在请求之间造成信息泄漏。
影响范围:8.5.0 - 8.5.59
危险级别:中等

CVE-2020-13943漏洞:该漏洞源于如果一个HTTP/2客户端连接到超过约定的最大数量的并发流连接(违反HTTP / 2协议),它是可能的后续请求在该连接可以包含HTTP头信息,包括HTTP / 2伪头,从先前的请求而不是标题。这可能导致用户看到对意外资源的响应。
影响范围:8.5.0 - 8.5.57
危险级别:中等

CVE-2020-13935漏洞:Apache Tomcat中的WebSocket存在安全漏洞,该漏洞源于程序没有正确验证payload的长度。攻击者可利用该漏洞造成拒绝服务(无限循环)
影响范围:8.5.0 - 8.5.56
危险级别:高危
CVE-2020-13934漏洞:当HTTP/1.1处理器升级到HTTP/ 2时,由于h2c直接连接未在发布后被释放,当有足够数量的此类请求,可能导致拒绝服务。
影响范围:8.5.1 - 8.5.56
危险级别:中等

CVE-2020-11996漏洞:通过恶意构造的HTTP/2请求序列可能会在几秒钟内触发高CPU使用率。如果在并发HTTP/2连接上发出足够数量的此类请求,服务器可能会变得无响应。
影响范围:8.5.0 - 8.5.55
危险级别:高危

CVE-2020-9484漏洞:源于持久化Session的远程代码执行漏洞,要利用该漏洞,攻击者需要同时满足以下4个条件:
1)    攻击者可以控制服务器上的文件名/文件内容;
2)    服务器上配置使用了PersistenceManager的FileStore;
3)    PersistenceManager配置了sessionAttributeValueClassNameFilter值为“NULL”或者其他宽松的过滤器,使得攻击者可以提供反序列化对象;
4)    攻击者知道FileStore使用的存储位置到可控文件的相对路径。
攻击者在同时满足以上4个条件时,可以发送一个恶意构造的请求,来造成反序列化代码执行漏洞。
影响范围:8.5.0 - 8.5.54
危险级别:高危

CVE-2020-1938漏洞:该漏洞是由于Tomcat AJP协议存在缺陷而导致,攻击者利用该漏洞可通过构造特定参数,读取服务器webapp下的任意文件。若目标服务器同时存在文件上传功能,攻击者可进一步实现远程代码执行。
影响范围:8.5.0 - 8.5.50
危险级别:高危

CVE-2020-1935漏洞:HTTP头解析代码使用了一种行结束(EOL)解析方法,允许将一些无效的HTTP头解析为有效的。如果Tomcat位于反向代理的后面,而反向代理以特定的方式错误地处理了无效的传输编码头,那么这就导致了HTTP请求走私的可能性。这种反向代理被认为是不太可能的。
影响范围:8.5.0 - 8.5.50
危险级别:低

CVE-2019-17569漏洞:该漏洞源于程序没有正确处理无效的Transfer-Encoding标头。攻击者可利用该漏洞造成Web缓存中毒,绕过Web应用程序防火墙保护及实施跨站脚本攻击
影响范围:8.5.0 - 8.5.50
危险级别:低

CVE-2019-17563漏洞:攻击者可借助FORM身份验证功能利用该漏洞访问其他用户的会话。
影响范围:8.5.0 - 8.5.49
危险级别:低

CVE-2019-12418漏洞:攻击者可通过实施中间人攻击利用该漏洞获取用户名和密码,访问JMX界面,控制Tomcat实例。
影响范围:8.5.0 - 8.5.47
危险级别:中等

CVE-2019-10072漏洞:没有解决写入时的HTTP/2 connection window耗尽问题。通过不为连接窗口(流0)发送WINDOW_UPDATE消息,客户端能够导致服务器端线程阻塞,最终导致线程耗尽和Dos。
影响范围:8.5.0 - 8.5.40
危险级别:高危

CVE-2019-0232漏洞:由于JRE将命令行参数传递给Windows的方式存在错误,会导致CGI Servlet受到远程执行代码的攻击。
触发该漏洞需要同时满足以下条件:
1)    系统为Windows
2)    启用了CGI Servlet(默认为关闭)
3)    启用了enableCmdLineArguments(Tomcat 9.0.*及官方未来发布版本默认为关闭)
影响范围:8.5.0 - 8.5.39
危险级别:高危

CVE-2019-0221漏洞:该漏洞源于WEB应用缺少对客户端数据的正确验证。攻击者可利用该漏洞执行客户端代码。SSI printenv命令回显用户提供的数据而不会转义,它很容易受到XSS的攻击。默认情况下禁用SSI。该printenv命令用于调试,不太可能出现在生产网站中。
影响范围:8.5.0 - 8.5.39
危险级别:低
原文地址:https://www.cnblogs.com/zh-dream/p/13624136.html