The Vulnerability
The Apache Tomcat team announced today that all Tomcat versions before 9.0.1 (Beta), 8.5.23, 8.0.47 and 7.0.82 contain a potentially dangerous remote code execution (RCE) vulnerability on all operating systems if the default servlet is configured with the parameter readonly
set to false
or the WebDAV servlet is enabled with the parameter readonly
set to false
.
This configuration would allow any unauthenticated user to upload files (as used in WebDAV). It was discovered that the filter that prevents the uploading of JavaServer Pages (.jsp) can be circumvented. So JSPs can be uploaded, which then can be executed on the server.
Now since this feature is typically not wanted, most publicly exposed system won’t have readonly
set to false
.
This security issue (CVE-2017-12617) was discovered after a similar vulnerability in Tomcat 7 on Windows CVE-2017-12615 has been fixed.
Unfortunately it has been publicly disclosed in the Tomcat Bugtracker on the 20th of September.
Updating Tomcat to a version where the vulnerability is fixed is recommended in all cases.
(The setting could be enabled by accident or other vulnerable combinations could be discovered.)
Part of the original announcement:
CVE-2017-12617 Apache Tomcat Remote Code Execution via JSP Upload Severity: Important Versions Affected: Apache Tomcat 9.0.0.M1 to 9.0.0 Apache Tomcat 8.5.0 to 8.5.22 Apache Tomcat 8.0.0.RC1 to 8.0.46 Apache Tomcat 7.0.0 to 7.0.81 Description: When running with HTTP PUTs enabled (e.g. via setting the readonly initialisation parameter of the Default servlet to false) it was possible to upload a JSP file to the server via a specially crafted request. This JSP could then be requested and any code it contained would be executed by the server. Mitigation: Users of the affected versions should apply one of the following mitigations: - Upgrade to Apache Tomcat 9.0.1 or later - Upgrade to Apache Tomcat 8.5.23 or later - Upgrade to Apache Tomcat 8.0.47 or later - Upgrade to Apache Tomcat 7.0.82 or later Credit: This issue was first reported publicly followed by multiple reports to the Apache Tomcat Security Team. History: 2017-10-03 Original advisory
The Exploit
The publicly described exploit is as simple as sending a special crafted HTTP PUT
request with a JSP as payload to a Tomcat server.
The code is then executed when the newly uploaded JSP is accessed via an HTTP client (e.g. web browser):
The Misconfiguration
The misconfiguration in the default servlet can be spotted by checking if the web.xml
of the default servlet contains an init-param like this (typically there are other init-params set):
Please note: that the misconfiguration could also take place in code or the configuration of the WebDAV servlet (if enabled).
The documentation of the default servlet talks about the read only param like this:
Is this context “read only”, so HTTP commands like PUT and DELETE are rejected? [true]
Since this sentence does not mention the dangers of this param we suggested a change of said documentation.
The Mitigation
Updating Tomcat to a version where the vulnerability is fixed (e.g. Tomcat 8.5.23) is recommended.
The readonly
init-param shouldn’t be set to false
. If this param is left to the default (true
) an attacker has not been able to upload files.
On this occasion it’s also a good idea to make sure that you don’t have the same vulnerability in custom PUT
implementations (also see: Unrestricted File Upload).
Additionally, it’s of course also possible to block PUT
and DELETE
requests on the frontend server (e.g. on the Web Application Firewall (WAF)).
Final Thoughts
In our eyes it is almost always wrong to set readonly
to false
and hopefully most publicly accessible Tomcat servers don’t have it set to false anyways.
If you are a user of Apache Tomcat it is recommended to subscribe to the tomcat-announce mailinglist to get information
about new releases and security vulnerabilities directly from the Tomcat team.
Update for developers (04 Oct 2017)
On some sites on the Internet (e.g. on Stack Overflow) you find the information that you should set readonly
to false
to make
your custom servlet accept PUT
or DELETE
requests. That is simply wrong!
Update (05 Oct 2017)
Updated the blog post to better point out that an upgrade to a fixed Tomcat version is (of course) recommended. Added the original announcement.
Update (09 Oct 2017)
Extended Mitigation chapter, improved wording.