一个平时没注意过的问题。
从Tomcat 8.5版本开始,若URL中存在部分特殊字符,会产生400报错。本以为修复方法和其他404、5XX报错页面没什么不同,结果并不简单。因为这个400报错是由于Tomcat无法解析字符导致的报错,并不通过代码层面,所以一般的错误页面自定义配置就会失效。
隐藏Tomcat 400报错
报错如下图所示:
查看Tomcat文档 https://tomcat.apache.org/tomcat-8.5-doc/config/http.html ,其中relaxedPathChars
和relaxedQueryChars
中写明,若存在" < > [ \ ] ^ ` { | }
符号,Tomcat无法解析URI,产生报错。
所以必须采用其他方法进行修复,这里提供隐藏报错详细信息的修复方式。
在server.xml
中添加一个ErrorReportValve
,将showReport
设置为false
就隐藏了详细报错信息,showServerInfo
设置为false
是隐藏Tomcat版本信息。
1 | <Valve className="org.apache.catalina.valves.ErrorReportValve" |
重启Tomcat,再次访问效果如下:
虽然没有彻底自定义界面,但好歹也隐藏掉了报错信息。
附加
本地快速复现漏洞,得善用docker。通过docker可以快速构造好需要的环境,可能节省很多亲自搭建环境的时间,如果让我自己来搭的话指不定要多久,说不定还会碰到各种环境不兼容的问题,有现成的直接用就非常爽了。比如这里我需要tomcat 9,直接在dockerhub上搜索tomcat9,然后随便点击进一个项目。
复制Docker Pull Command,在命令行中输入,即可把镜像拉下来
镜像拉下来后,启动镜像
1 | docker run -it --rm -p 8888:8080 donglsheng/tomcat9_jdk8 |
其中,-t
选项让Docker分配一个伪终端(pseudo-tty)并绑定到容器的标准输入上, -i
则让容器的标准输入保持打开,--rm
是在运行完成之后清除容器,-p
是指定映射端口,其中8888是容器外端口,8080是容器内端口。
这样启动并不能得到一个交互式的shell,如果需要执行容器内命令,在后方加上/bin/bash
就是进入容器内的shell。
1 | docker run -it --rm -p 8888:8080 donglsheng/tomcat9_jdk8 /bin/bash |
进入docker后,可能找不到相关的路径,这时需要去查找该镜像的制作人在Docker Hub中有没有写明路径或相关教程。没有的话再看容器启动时是否会显示路径。
Dockerfile中都会写明具体路径
进入shell后查找该路径即可找到tomcat的位置。
cd /usr/local/soft/tomcat/
就到了tomcat目录,其中conf
目录就是配置文件所在的目录,需要更改的server.xml
就在该路径下