This site is the archived OWASP Foundation Wiki and is no longer accepting Account Requests.
To view the new OWASP Foundation website, please visit https://owasp.org

Difference between revisions of "Securing tomcat"

From OWASP
Jump to: navigation, search
m (Logging)
m
Line 64: Line 64:
 
:remove CATALINA_HOME/server/lib/org (created when extracting the ServerInfo.properties file)
 
:remove CATALINA_HOME/server/lib/org (created when extracting the ServerInfo.properties file)
  
* 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.''
+
* 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.  Place the following within the ''web-app'' tag (after the ''welcome-file-list'' tag is fine). ''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-page>
 
     <exception-type>java.lang.Exception</exception-type>
 
     <exception-type>java.lang.Exception</exception-type>
Line 119: Line 119:
 
   org.apache.juli.FileHandler.directory = ${catalina.base}/logs
 
   org.apache.juli.FileHandler.directory = ${catalina.base}/logs
 
   org.apache.juli.FileHandler.prefix = APP_NAME.
 
   org.apache.juli.FileHandler.prefix = APP_NAME.
  java.util.logging.ConsoleHandler.level = ALL
 
  java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
 
  
 
Further details on logging configuration can be found in the [http://tomcat.apache.org/tomcat-5.5-doc/logging.html tomcat logging documentation.]
 
Further details on logging configuration can be found in the [http://tomcat.apache.org/tomcat-5.5-doc/logging.html tomcat logging documentation.]
  
''TODO - details on disabling most of catalina.out output''
+
If you find you get logging output duplicated in catalina.out, you most likely have unnecessary entries for ''java.util.logging.ConsoleHandler'' in your logging configuration file.
  
 
== Encryption ==
 
== Encryption ==
Line 149: Line 147:
 
* Use IIS / Apache running on port 80 and mod_jk to proxy requests to Tomcat
 
* Use IIS / Apache running on port 80 and mod_jk to proxy requests to Tomcat
  
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;
+
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);
 
* Use Apache running on port 80 and mod_jk (or mod_proxy_ajp) to proxy requests to Tomcat
 
* Use Apache running on port 80 and mod_jk (or mod_proxy_ajp) to proxy requests to Tomcat
 
* Run Tomcat as root, but in a chroot jail
 
* Run Tomcat as root, but in a chroot jail
Line 156: Line 154:
 
* Run [http://www.squid-cache.org/ Squid] as a web accelerator in front of Tomcat
 
* Run [http://www.squid-cache.org/ Squid] as a web accelerator in front of Tomcat
 
* Use JSVC/procrun
 
* Use JSVC/procrun
 +
Each of the above options '''may''' bring extra security concerns which are outside the scope of this document.
  
 
=== Cleartext Passwords in CATALINA_HOME/conf/server.xml ===
 
=== Cleartext Passwords in CATALINA_HOME/conf/server.xml ===

Revision as of 16:12, 17 April 2007

Introduction

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.


Software Versions

The first step is to make sure you are running the latest stable releases of software;

  • Java Runtime Environment (JRE) or SDK
  • Tomcat
  • 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

UNIX

  • 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 (400)
  • Make sure tomcat user has read/write access to /tmp and write (300 - yes, only write/execute) access to CATALINA_HOME/logs

Windows

  • 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.
  • 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.

Common

  • 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). Note that it can be useful to keep the manager webapp installed if you need the ability to redeploy without restarting Tomcat. If you choose to keep it please read the section on Securing the Manager WebApp.
  • Remove CATALINA_HOME/conf/Catalina/localhost/host-manager.xml and CATALINA_HOME/conf/Catalina/localhost/manager.xml (again, if you are keeping the manager application, do not remove this).
  • 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>  <!-- make sure this is false -->
   </init-param>
   <load-on-startup>1</load-on-startup>
 </servlet>
  • Remove version string from HTTP error messages by repacking CATALINA_HOME/server/lib/catalina.jar with an updated ServerInfo.properties file.
unpack catalina.jar
 cd CATALINA_HOME/server/lib
 jar xf catalina.jar org/apache/catalina/util/ServerInfo.properties
update ServerInfo.properties by changing server.info line to server.info=Apache Tomcat
repackage catalina.jar
 jar uf catalina.jar org/apache/catalina/util/ServerInfo.properties
remove CATALINA_HOME/server/lib/org (created when extracting the ServerInfo.properties file)
  • 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. Place the following within the web-app tag (after the welcome-file-list tag is fine). 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>
  • Rename CATALINA_HOME/conf/server.xml to CATALINA_HOME/conf/server-original.xml and rename CATALINA_HOME/conf/server-minimal.xml to CATALINA_HOME/conf/server.xml. The minimal configuration provides the same basic configuration, but without the nested comments is much easier to maintain and understand. Do not delete the original file as the comments make it useful for reference if you ever need to make changes - e.g. enable SSL.
  • Replace the server version string from HTTP headers in server responses, by adding the server keyword in your Connectors in CATALINA_HOME/conf/server.xml
 <Connector port="8080" ...
            server="Apache" />  <!-- server header is now Apache -->
  • Start Tomcat, deploy your applications into CATALINA_HOME/webapps and hope it works!

Protecting the Shutdown Port

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 the shutdown 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 the shutdown command can be changed to something other than the string SHUTDOWN. However, it's wise to take the following precautions;

  • if you are running a publicly accessible server make sure you prevent external access to the shutdown port by using a suitable firewall.
  • change the shutdown command in CATALINA_HOME/conf/server.xml and make sure that file is only readable by the tomcat user.
 <Server port="8005" shutdown="ReallyComplexWord">
  • if this is still a big problem for you then check this thread, from the Tomcat mailing list, for alternatives (they all involve code customisation though).


Securing Manager WebApp

  • By default there are no users with the manager role. To make use of the manager webapp you need to add a new role and user into the CATALINA_HOME/conf/tomcat-users.xml file.
 <role rolename="manager"/>
 <user username="darren" password="ReallyComplexPassword" roles="manager"/>
  • Using a valve to filter by IP or hostname to only allow a subset of machines to connect (i.e. LAN machines). Add one of the following within the Context tag in CATALINA_HOME/conf/Catalina/localhost/manager.xml
 <!-- 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" />
  • You can rename the manager webapp to something else, e.g. foobar
    • Move CATALINA_HOME/conf/Catalina/localhost/manager.xml to CATALINA_HOME/conf/Catalina/localhost/foobar.xml
    • Update the docBase attribute within CATALINA_HOME/conf/Catalina/localhost/foobar.xml to ${catalina.home}/server/webapps/foobar
    • Move CATALINA_HOME/server/webapps/manager to CATALINA_HOME/server/webapps/foobar

Logging

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 to CATALINA_HOME/logs/catalina.out. To place webapp log entries in individual log files create a logging.properties file similar to the following within CATALINA_HOME/webapps/APP_NAME/WEB-INF/classes (change the APP_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 for java.util.logging.ConsoleHandler in your logging configuration file.

Encryption

  • 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.


Java Security

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.


Miscellaneous

Using Port 80

If you are on a Windows machine you will be able to change the port attribute of the connector within the Catalina 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;

  • Use IIS / Apache running on port 80 and mod_jk to proxy requests to Tomcat

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);

  • Use Apache running on port 80 and mod_jk (or mod_proxy_ajp) to proxy requests to Tomcat
  • Run Tomcat as root, but in a chroot jail
  • Use a tool like authbind to enable a non root user to bind to ports below 1024
  • Use a port forwarder such as Iptables to redirect incoming requests from 8080 to 80. This has the disadvantage that internal redirects still need to use 8080.
  • Run Squid as a web accelerator in front of Tomcat
  • Use JSVC/procrun

Each of the above options may bring extra security concerns which are outside the scope of this document.

Cleartext Passwords in CATALINA_HOME/conf/server.xml

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;

  • make sure the database user only has access to the databases and tables they need (also limit rights as necessary).
  • make sure the raw database files are only accessible to the user running the database services (e.g. mysql/postgresql user)
  • make sure the Tomcat configuration files are only accessible to the tomcat user