Apache Tomcat Security Constraint Bypass Vulnerability CVE-2017–5664
Summary
Apache Tomcat is an open source Java Servlet and JavaServer Pages (JSP) container developed and maintained by the Apache Software Foundation. As a lightweight, fast, and scalable web server, it is used to execute Java Servlets and JavaServer Pages technologies.
Tomcat can function as a standalone server, serving as a web server for Java applications, or it can be integrated as a Servlet container into other web servers (such as the Apache HTTP Server). It handles HTTP requests, forwards them to the corresponding Servlet or JSP for processing, then returns the results to the client.
Tomcat provides various features, including connection pooling, session management, security, Web application deployment, load balancing, and more. It is a popular deployment environment for enterprise-level Java web applications and is widely used for developing and deploying Java Web applications and services.
The Tomcat-catalina component is responsible for handling core functionalities such as HTTP request processing, response handling, session management, Servlet container, connection pool, thread pool, and more. It serves as the core engine of the Tomcat server.
The author selected the common Tomcat component vulnerabilities for research by analyzing components deployed in hundreds of real projects. This analysis is CVE-2017–5648.
Information
·Name:Apache Tomcat Security Constraint Bypass Vulnerability
·Number:CVE-2017–5664
·Type:CWE-755 Improper Handling of Exceptional Conditions
·CVSS Score:CVSS v3.1:7.5
·Severity Level:high
When the Tomcat-catalina component handles requests for access to incorrect resources, such as 404, 500, If the server has custom error pages, the request can be passed to the DefaultServlet, potentially resulting in the rewriting of the error pages, creating the vulnerability.
The readOnly attribute of the DefaultServlet is set to false by default (true by default), and if custom static file-based error pages are present, they can override the error pages.
Affected version
Apache Tomcat 9.0.0.M1 ~ 9.0.0.M20
Apache Tomcat 8.5.0 ~ 8.5.14
Apache Tomcat 8.0.0.RC1 ~ 8.0.43
Apache Tomcat 7.0.0 ~ 7.0.77
Analysis
Tomcat has two core functionalities, the connector of it is responsible for listening to network ports, receiving and responding to network requests, and converting the received network byte stream into a Tomcat Request and then into the standard ServletRequest to the container, at the same time, converting the ServletResponse passed by the container into a Tomcat Response, and then into the network byte stream.
The container has an engine that can manage multiple virtual hosts. Each virtual host can manage multiple Web applications. Each Web application has multiple Servlet wrappers. Engine, Host, Context, and Wrapper, and the four containers belong to a parent-child relationship.
The final processing of the request is done by the Servlet’s service method, which dispatches the processing functions based on the request method.
According to the official Tomcat documentation, the DefaultServlet serves static resources.
It is configured in the $CATALINA_BASE/conf/web.xml file, with its readonly attribute set to true by default. This means that HTTP request methods like PUT or DELETE are denied.
<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>
<load-on-startup>1</load-on-startup>
</servlet>
…
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
It’s also clear from its code that if ReadOnly is set to true, it will return error code 403.
If a non-existent page is requested, the user will be redirected to the error page. As shown below, the user has been redirected to our 404.html error page.
At this stage, the request should be treated as a GET request, but the original method is preserved and assigned to the doPUT function. Consequently, the configured 404.html page is overwritten after the execution of resources.write() in DefaultServlet.java at line 546.
Reproduction
To modify the DefaultServlet configuration, locate the conf/web.xml file in the Tomcat directory and make the following changes:
<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>
<load-on-startup>1</load-on-startup>
<init-param>
<param-name>readonly</param-name>
<param-value>false</param-value>
</init-param>
</servlet>
Next, configure a custom static error page.
<error-page>
<error-code>404</error-code>
<location>/404.html</location>
</error-page>
When attempting to access the error page at this stage, the message ‘this is an error page!’ is displayed.
Use the PUT method to request an error page.
curl -i -T ../test.txt http://192.168.213.140:8080/examples/123.jsp
To write to the 404.html file, the DefaultServlet invokes the doPUT method.
Requesting it again confirms that the default error page has been modified.
Fix
Several solutions exist to address this vulnerability:
1. Upgrade Tomcat to a version that doesn’t have this vulnerability
Upgrade to Apache Tomcat >= 9.0.0.M21
Upgrade to Apache Tomcat >= 8.5.15
Upgrade to Apache Tomcat >= 8.0.44
Upgrade to Apache Tomcat >= 7.0.78
The official fix solution by Tomcat is to validate the service method and treat it as a GET request if it is forwarded due to an error.
The fix version can be downloaded from the Tomcat website at
2. Modify the web.xml Configuration
Setting the DefaultServlet’s ReadOnly attribute to true makes the servlet reject PUT and DELETE requests.
3. Modify custom error page file types
DefaultServlet files such as .html files only handle the static requests. If the custom error page is 404.jsp, it is handled by the jspServlet to forward the request.