Most weaknesses in Apache Tomcat come from incorrect or inappropiate configuration. It is nearly always possible to make Tomcat more secure than the default out of the box installation. What follows documents best practices and recommendations on securing a production Tomcat server, whether it be hosted on a Windows or Unix based operating system. Please note that the section ordering is not a representation of the section importance.
The first step is to make sure you are running the latest stable releases of software;
- Java Runtime Environment (JRE) or SDK
- Third party libraries
This does not mean you have to upgrade all your production servers to a new (and potentially buggy) release which has just been made available to the public. What you must do is download the latest stable bugfix release that has continual support. For the JRE and Tomcat you should be looking at the last digits in the version number (5.5.X) as it represents the bugfix information. The bugs fixed in these releases are publicly available so if you don't upgrade you could be providing attackers with a very easy route to compromise your server.
Installation of Apache Tomcat 5.5
- Create a tomcat user/group
- Download and unpack the core distribution (referenced as CATALINA_HOME from now on)
- Change CATALINA_HOME ownership to tomcat user and tomcat group
- Change files in CATALINA_HOME/conf to be readonly
- Make sure tomcat user has read/write access to /tmp and write (yes, only write) access to CATALINA_HOME/log
- Change the default HTTP port to something other than 8080, by editing the Connector port attribute within the Catalina Service (CATALINA_HOME/conf/server.xml). This ensures less scripted attacks on your server, but in no way helps protect you from vulnerabilities.
- Download the core windows service installer
- Start the installation, click Next and Agree to the licence
- Untick native, documentation, examples and webapps then click Next
- Choose an installation directory (referenced as CATALINA_HOME from now on), preferably on a different drive to the OS.
- Change the default HTTP port to something other than 8080. This ensures less scripted attacks on your server, but in no way helps protect you from vulnerabilities.
- Choose an administrator username (NOT admin) and a secure password that complies with your organisations password policy.
- Complete tomcat installation, but do not start service.
- TODO: filesystem security
- Remove everything from CATALINA_HOME/webapps (ROOT, balancer, jsp-examples, servlet-examples, tomcat-docs, webdav)
- Remove everything from CATALINA_HOME/server/webapps (host-manager, manager)
- Make sure the default servlet is configured not to serve index pages when a welcome file is not present. In CATALINA_HOME/conf/web.xml
<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>
- Replace default HTTP error pages (i.e. 404) by adding the following into CATALINA_HOME/conf/web.xml. The default HTTP error pages show the full Tomcat version which is unnecessary information disclosure. The following solution is not ideal as it produces a blank page because Tomcat cannot find the file specified, but without a better solution this, at least, achieves the desired result. A well configured web application will override this default in CATALINA_HOME/webapps/APP_NAME/WEB-INF/web.xml so it won't cause problems.
<error-page> <error-code>404</error-code> <location>/404.jsp</location> </error-page>
- Replace default error page (default is stacktrace) by adding the following into CATALINA_HOME/conf/web.xml. The default error page shows a full stacktrace which is a disclosure of sensitive information. The following solution is not ideal as it produces a blank page because Tomcat cannot find the file specified, but without a better solution this, at least, achieves the desired result. A well configured web application will override this default in CATALINA_HOME/webapps/APP_NAME/WEB-INF/web.xml so it won't cause problems.
<error-page> <exception-type>java.lang.Exception</exception-type> <location>/error.jsp</location> </error-page>
- Consider replacing CATALINA_HOME/conf/server.xml with CATALINA_HOME/conf/server-minimal.xml - work out what we lose
- is it easy to remove the version string from the server HTTP header (Apache-Coyote/1.1) ?
- Start Tomcat, deploy your applications into CATALINA_HOME/webapps and hope it works!
- TODO: Audit trails
User data, whether it be HTTP headers or parameters, should '"never"' be trusted. It is usually the responsibility of the application to validate data, but it is important that one poorly written application doesn't compromise Tomcat as a whole.
- global filters
- global error pages (see above)
- permission lockdown (see below)
- SSL for password or other sensitive data exchange (bordering on application security, not specific to tomcat)
- SSL for connections (JDBC, LDAP, etc ..)
- The Tomcat documentation clearly explains how to enable SSL.
Running Tomcat with a Security Manager
The default Tomcat configuration provides good protection for most requirements, but does not prevent a malicious application from compromising the security of other applications running in the same instance. To prevent this sort of attack, Tomcat can be run with a Security Manager enabled which strictly controls access to server resources. Tomcat documentation has a good section on enabling the Security Manager.
- TODO: Storing cleartext passwords in configuration files (article to add)