Apache Tomcat (Tomcat) is a widely used Java application server with over one million downloads per month. Most vulnerabilities of Tomcat are discovered by the Tomcat community or security researchers, and are quickly patched. Tomcat security is a matter of balancing convenience and restrictions. In this tutorial, we will provide an overview of the security vulnerabilities in Tomcat.
Table Of Contents
Apache Tomcat is an open source Java Servlet container developed by the Apache Software Foundation. It is written in Java and available under the Apache Software License.
A vulnerability is a flaw in code or design that creates a security risk. Vulnerabilities create possible attack vectors, through which intruders can hack the system.
All of Tomcat’s known security vulnerabilities as well as fixed versions are available here. Most weaknesses of Tomcat actually come from incorrect configuration. In this example, I will show you how to secure Tomcat by adjusting the
The example code in this article was built and run using:
- Java 1.8
- Tomcat 9.0.6 and 8.0.12
- Fiddler 2
To install Tomcat 9 on a Windows 7 system, follow these instructions. Make sure you already have JDK 8 installed.
Check the installed Tomcat
webapps directory. It includes five sub-folders:
Start Tomcat with the default setting. In this step, I will demonstrate two security vulnerabilities caused by the default setting.
- Go to the Tomcat 9
startup.batto start the server.
- Confirm that the server is up by checking the server output.Tomcat Server Output
16-Mar-2018 16:41:10.232 INFO [main] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [C:\MaryZheng\tools\apache-tomcat-9.0.6\webapps\manager] has finished in  ms 16-Mar-2018 16:41:10.233 INFO [main] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [C:\MaryZheng\tools\apache-tomcat-9.0.6\webapps\ROOT] 16-Mar-2018 16:41:10.322 INFO [main] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [C:\MaryZheng\tools\apache-tomcat-9.0.6\webapps\ROOT] has finished in  ms 16-Mar-2018 16:41:10.328 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["http-nio-8080"] 16-Mar-2018 16:41:10.350 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["ajp-nio-8009"] 16-Mar-2018 16:41:10.356 INFO [main] org.apache.catalina.startup.Catalina.start Server startup in 3234 ms
- Start the Fiddler. Click here to install it.
- Open a web browser window and go to
- You should see a web page with Tomcat server information.
- Switch to the
Fiddlerapplication. Click on the
Inspectorstab, then the
Headerstab. The Tomcat 9.0.6 hides the sever information, but Tomcat 8.0.12 shows the server information.
- Switch to your web browser, and then go to
http://localhost:8080/bad. You should see the 404 – Not found error page, which displays the server information.
Displaying the server and version details are two common security vulnerabilities. I will show you how to adjust the
server.xml to hide them.
We should remove everything from
webapps because it presents security risks according to Apache documentation. It can be useful to keep the
manager web application installed if you need to auto-deploy the application without restarting Tomcat. If you do, please follow the instruction here.
We will demonstrate a security risk with the steps below:
- Start the Tomcat server with
- Start the Fiddler application
- Navigate to
- Enter the login, for example, I enter the username as
hacker, password as
- Capture the
Httpheader and you will see the
Authorizationdisplays as a clear text.
- Navigate to
https://www.base64decode.org/; Decode the clear text value, then you get the username and password.
server.xml file is a deployment descriptor which is used to specify server configurations. We will modify it for better security using the steps below:
- Delete all default comments
- Hide the server from the
- Disable the displaying of server version details
- Disable auto-deploy for production servers
- Disable the shutdown port to protect the server from unintended shutdowns
Note: Tomcat 9.0.6 already hides number 2, but 8.0.12 does not. You can hide it by altering the
Connector to add the
server attribute to some dummy name.
<Connector port="8080" ... server="SOMEDUMMY" />
Updated server.xml below:
<?xml version="1.0" encoding="UTF-8"?> <Server port="-1" shutdown="SHUTDOWN"> <Listener className="org.apache.catalina.startup.VersionLoggerListener" /> <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" /> <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" /> <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" /> <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" /> <GlobalNamingResources> <Resource name="UserDatabase" auth="Container" type="org.apache.catalina.UserDatabase" description="User database that can be updated and saved" factory="org.apache.catalina.users.MemoryUserDatabaseFactory" pathname="conf/tomcat-users.xml" /> </GlobalNamingResources> <Service name="Catalina"> <Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" /> <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" /> <Engine name="Catalina" defaultHost="localhost"> <Realm className="org.apache.catalina.realm.LockOutRealm"> <Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase" /> </Realm> <Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="false"> <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="localhost_access_log" suffix=".txt" pattern="%h %l %u %t "%r" %s %b" /> <Valve className="org.apache.catalina.valves.ErrorReportValve" showReport="false" showServerInfo="false"/> </Host> </Engine> </Service> </Server>
- line 3: disable shutdown port
- line 31: disable auto-deploy
- line 37-39: disable error page to show the server information
Now, start Tomcat and repeat step 4. You will see that the Tomcat server and version information is now hidden.
The web.xml is a deployment descriptor file which describes how to deploy a web application in Tomcat. Tomcat has already addressed the vulnerability designated as CVE-2017-12617 on October 3, 2017 by setting the
readonly initialization parameter of the
DefaultServlet to true.
Here is the default setting for
<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>
We need update it to include
readOnly = true.
readOnly = true
<init-param> <param-name>readonly</param-name> <param-value>true</param-value> </init-param>
In this example, we manually use the
Fiddler web application to find two known vulnerabilities. Then we demonstrated how to update the
server.xml to prevent them.
Tomcat is managed by the operating system and hosts web applications. Clients access it via the network. So we should secure the network, operating systems, as well as the web applications hosted at Tomcat Server.
We should also use scanning tools to test the web application vulnerability. There are a number of well-respected scanning tools available. e.g. IBM Rational AppScan and Acunetix Web Vulnerability Scanner.
Tomcat is an active open source project, the easiest way to improve the security of your instance is to keep your version up to date and keep up with the Tomcat mailing lists. The CIS Tomcat Security Benchmark includes a long list of other best practices you should consider implementing once you have completed the basic due diligence on your system.