* Content should provide a link and references to
- SecureTomcat - http://securetomcat.googlecode.com
Released 14/1/2007
Darren Edmonds
Most weaknesses in Apache Tomcat come from incorrect or inappropriate 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;
Many software projects, including Tomcat and Java, maintain multiple branches. New features are added to more recent branches, the older branches receive only bug-fixes and security updates. This allows developers to advance the software without disrupting production environments. Be aware of which branch you have deployed, and track new releases within that branch.
For example, if you are running Tomcat 5.5.26, you should watch for new versions within the 5.5 branch (e.g. 5.5.27) and upgrade to this bug-fix version. If you are content to stick with the Tomcat 5.5 branch then it is not necessary to upgrade to a new 6.0.18 version.
You should subscribe to announcement lists for Tomcat, and any other software you deploy, to stay abreast of new versions released due to security issues. As soon as a security issue is disclosed, potential attackers will begin trying to exploit that vulnerability. It is important that you upgrade your software before an attacker uses the vulnerability against you.
<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> <!-- make sure this is false --> </init-param> <load-on-startup>1</load-on-startup> </servlet>
cd CATALINA_HOME/server/lib jar xf catalina.jar org/apache/catalina/util/ServerInfo.properties
jar uf catalina.jar org/apache/catalina/util/ServerInfo.properties
<error-page> <exception-type>java.lang.Throwable</exception-type> <location>/error.jsp</location> </error-page>
<Connector port="8080" ... server="Apache" /> <!-- server header is now Apache -->
Tomcat uses a port (defaults to 8005) as a shutdown port. What this means is that to stop all webapps and stop Tomcat cleanly the shutdown scripts make a connection to this port and send theshutdown command. This is not as huge a security problem as it may sound considering the connection to the port must be made from the machine running tomcat and theshutdown command can be changed to something other than the string SHUTDOWN. However, it's wise to take the following precautions;
<Server port="8005" shutdown="ReallyComplexWord">
<role rolename="manager"/> <user username="darren" password="ReallyComplexPassword" roles="manager"/>
<user-data-constraint> <transport-guarantee>CONFIDENTIAL</transport-guarantee> <user-data-constraint>
<!-- allow only LAN IPs to connect to the manager webapp --> <!-- contrary to the current Tomcat 5.5 documation the value for allow is not a regular expression --> <!-- future versions may have to be specified as 192\.168\.1\.* --> <Valve className="org.apache.catalina.valves.RemoteAddrValve" allow="192.168.1.*" />
<!-- allow only LAN hosts to connect to the manager webapp --> <!-- contrary to the current Tomcat 5.5 documation the value for allow is not a regular expression --> <!-- future versions may have to be specified as *\.localdomain\.com --> <Valve className="org.apache.catalina.valves.RemoteHostValve" allow="*.localdomain.com" />
As of tomcat 5.5 logging is now handled by the commons-logging framework allowing you to choose your preferred logging implementation - log4j or standard JDK logging. By default the standard JDK logging is used (or a compatible extension called juli to be more precise), storing daily log files in CATALINA_HOME/logs.
By default additional webapp log entries are added to CATALINA_HOME/logs/catalina.YYYY-MM-DD.log and System.out/System.err are redirected toCATALINA_HOME/logs/catalina.out. To place webapp log entries in individual log files create alogging.properties file similar to the following within CATALINA_HOME/webapps/APP_NAME/WEB-INF/classes (change theAPP_NAME value to create a unique file for each webapp)
handlers = org.apache.juli.FileHandler, java.util.logging.ConsoleHandler org.apache.juli.FileHandler.level = ALL org.apache.juli.FileHandler.directory = ${catalina.base}/logs org.apache.juli.FileHandler.prefix = APP_NAME.
Further details on logging configuration can be found in the tomcat logging documentation.
If you find you get logging output duplicated in catalina.out, you most likely have unnecessary entries forjava.util.logging.ConsoleHandler in your logging configuration file.
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 onenabling the Security Manager.
It's always a good idea to start tomcat with the "-security" parameter. This also makes sure (among other things), that a webapplication isn't able to read/write/execute any file on the local filesystem without enabling it in the catalina.policy file. This effectively stops web shells like described here from working.
If you are on a Windows machine you will be able to change the port attribute of the connector within theCatalina service from 8080 to 80. This allows you to use tomcat directly to serve all requests. Depending on your requirements it may not be good enough to serve directly from Tomcat so you may like to consider;
On a UNIX machine only root is allowed to run services on ports below 1024 (kernel recompilation can overcome this). It is a very bad idea to run Tomcat as root, so the options are (in no particular order);
Each of the above options may bring extra security concerns which are outside the scope of this document.
When configuring a resource, such as a JDBC pool, it is necessary to include clear text username and password in CATALINA_HOME/conf/server.xml Best practices advice us never to store clear text passwords, but the following paragraphs highlight it is very difficult to avoid.
If one way encryption was used on the password it must be possible for a database connection to be established using a username and encrypted password - so the encrypted password is just as valuable as the clear text one to an attacker.
If two way encryption was used a keyfile is needed which must also live on the filesystem. To make it more secure a passphase is added to the keyfile which then has to be stored in the configuration as clear text - no improvement.
Encoding is security by obscurity and offers no form of protection (algorithms can be reverse engineered). What encoding does do is make huge amounts of overhead work - you need to customise Tomcat and the commons digester it uses to parse the config files. You'd also need a way to create encoded passwords.
In the case of a JDBC pool what you can do is;