Featured image of post 解决一个Tomcat错误信息泄露漏洞

解决一个Tomcat错误信息泄露漏洞

问题复现条件

第三方例行扫描,手工测试访问了一个我不存在的资源,通过构造错误的信息,让我的tomcat响应了400(正常应该是404),路径如下:

/host-manager/eam/vib?id=C:\

响应如下

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
HTTP状态 400 - 错误的请求
类型 异常报告

消息 在请求目标中找到无效字符。有效字符在RFC 7230和RFC 3986中定义

描述 由于被认为是客户端对错误(例如:畸形的请求语法、无效的请求信息帧或者虚拟的请求路由),服务器无法或不会处理当前请求。

例外情况

java.lang.IllegalArgumentException: 在请求目标中找到无效字符。有效字符在RFC 7230和RFC 3986中定义
	org.apache.coyote.http11.Http11InputBuffer.parseRequestLine(Http11InputBuffer.java:509)
	org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:513)
	org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
	org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:881)
	org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1647)
	org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
	org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
	org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
	org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
	java.lang.Thread.run(Thread.java:750)
):注意 主要问题的全部 stack 信息可以在 server logs 里查看

Apache Tomcat/8.5.76

测试者认为我的服务器没有对错误信息进行过滤,泄漏了服务器路径和页面源代码等敏感信息。

引发问题的原因

我觉得这其实是属于误报,tomcat高版本严格按照RFC 3986规范解析地址,该规范只允许包含 a-zA-Z 0-9 - _ . ~ 以及所有保留字符 ! * ’ ( ) ; : @ & = + $ , / ? # [ ],但是项目在发起请求的参数中出现\,所以tomcat直接返回了错误,本质上这个东西并不能泄露什么信息,但是因为报了嘛,我们就直接解决掉。

解决方式

解决方式比较简单,直接在tomcat上放行这些特殊字符,修改tomcat的conf/server.xml文件在connector上配置如下:

1
2
3
4
5
    <Connector port="8080" URIEncoding="UTF-8" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" 
               relaxedPathChars="^`\|{}[],%" 
               relaxedQueryChars="^`\|{}[],%" />

网络上的方案我也看了,如果你照抄你绝对解决不了这个问题。