Basic Tomcat security configuration recommendations

What is Tomcat and how does it work?

At its core, Apache Tomcat is an open source servlet and JSP container. 

With Java, there are some small pieces of code to serve application requests, without having to worry about how the underlying protocol works (requests/responses in HTTP, FTP, SMTP or others). These are servlets.

Tomcat receives a request, parses it into a Request object, and calls the Servlet. That Servlet generates all the output in a Response object, and Tomcat sends this back as a response.


A typical example, with a Web application, using Tomcat and the Apache web server:

The web server receives the client's request, forwards it to the application, receives the response from the application, and finally forwards it to the client.


At high level, it is crucially important to understand this architecture. How the application works is most often independent from how the web server ant the Tomcat server are working. 

Tomcat hardening and secure configuration

First things first: Updates!

Use the latest supported versions of Tomcat and Java. Make sure to check for compatibility with BMC products using the Compatibility Matrix. It is evidently important to run an up to date version of your BMC products!


Locking down a Tomcat server is a balancing act: We don't want to overdo the securing to a point where users experience a slowdown in performance, or not able to access the applications altogether. This portion is going to be determined by many factors, mainly to do with a particular environment. What works well for one environment will not necessarily work for another.

It is important that these configuration changes are tested before making them in a live production system.

Tomcat Out Of the Box

By default tomcat can be deployed very quickly to start publishing web applications. The default install is not secured and must be reviewed, especially if the instance is accessible over the web.

The default tomcat is configured in none SSL/TLS mode (plain text HTTP), and also includes defaults applications, An attacker could use these applications to gain access to other portions of the system.
 
We'll start by removing these default applications and get Tomcat into secure TLS mode (Remember? SSL is deprecated!).

Tomcat Default Applications

Tomcat deploys by default a set of applications that have different purposes for Tomcat, but that are typically of no use for BMC applications. Here is a brief summary of what these applications are and why they can be removed.

  • ROOT - This is the default Tomcat application when going to http://severname:8080, showing that Tomcat "is running". This is typically not needed and should be deleted.
  • Examples - Used to gather informations about the system and other applications, it is strongly recommended to be deleted.
  • Host Manager - This application is not accessible by default as no users are configured with the necessary access, and is used to create and manage virtual hosts. If you need this application on your Tomcat instance, please review the official documentation to secure it.  Otherwise it should be deleted.
  • Manager - Not accessible by default (no users configured), it is used to remotely deploy web applications. Its also frequently used by attackers to gain access to the host, in general because of weak security configuration and credentials. If there is a need to do remote deployment of applications then make sure you secure this application by following guidance from Apache on the docs page, otherwise it should be deleted.
  • Docs - Holds the doc pages of Apache and also hold version information. You can get the latest docs information at https://tomcat.apache.org so we really don't need this. This can be deleted.


If deleting or removing these applications is not possible for some reason, then move them into another location on the system away from the publishing area in Tomcat /webapps. After moving or deleting the the default applications restart Tomcat to make sure it comes up correctly, with no errors in the catalina.log file.

SSL/TLS Mode

Lets start with a "SSL is dead, long live TLS!".

Historically, TLS v1.0 is the equivalent and successor of SSL v3.0. Both protocols are different, SSL is flawed in many ways and was replaced by TLS. In the average everyday language, SSL is still understood and used as this equivalent, but nothing could be more wrong at a technical level. With respect to technical accuracy, this document will not use the SSL terminology.

The advantages of using TLS has long been documented and should be the first thing you do when installing Tomcat in a secure configuration. TLS certificates are used to protect sensitive information as it crosses networks, by means of encryption, and provides a framework of Trusted and Trustees. TLS is configured in the tomcat server.xml file. 

By default tomcat is installed in HTTP mode, on TCP port 8080. To enable TLS, we need to add the correct entries in the server.xml file.

The format of the connector port in server.xml will look something like the below

<Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="<https_port>" />

   <Connector port="<https_port>"
                      protocol="org.apache.coyote.http11.Http11NioProtocol" SSLEnabled="true"
                       maxThreads="150" scheme="https" secure="true"
                       maxHttpHeaderSize="32768"
                       clientAuth="want"
                       sslEnabledProtocols="TLSv1.2"
                       ciphers= "<list of ciphers to use>"
              keystoreFile="<path to keystore location>"
                      keystorePass="<keystore password>"
                      keyAlias="<key alias name in the keystore>"
                      truststoreFile="<truststore location optional>"
                      truststorePass="<truststore password>" />

The above entries need to be in the server.xml file to enable TLS mode. See Creating a keystore From Tomcat Webserver Video for instructions on how to create the keystore, sign the request and import the certificate onto the tomcat web server (the video is based on the BMC TrueSight Presentation Server, but is valid for any tomcat web server)

Redirects & HTTPS Only

In some instances you may not want the port of the Tomcat server to be published along with the URL. The best method to do this is to have a Load Balancer rewrite the URL and remove the port from the it. If you don't have or use a Load Balancer you will have to make some changes to the tomcat server.xml & web.xml files. You may also want to only allow HTTPS connections. Again this best done at the Load Balancer level, but it can also be achieved using Tomcat's configuration files. The configurations below uses Tomcat auto redirect ports (80 & 443), which have the affect of removing the ports from the URL; All of this is done in the server.xml file

In the server.xml file change the Connector port to 80, redirect port to 443 & HTTPS connector port to 443:


<Connector port="80" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="443" />    

<Connector port="443" protocol="org.apache.coyote.http11.Http11NioProtocol" SSLEnabled="true"            
                       maxThreads="150" scheme="https" secure="true"
                       maxHttpHeaderSize="32768"
                       clientAuth="want"
                      sslEnabledProtocols="TLSv1.2"
                       ciphers="HIGH:!aNULL:!RC4:!MD5:@STRENGTH"
              keystoreFile="path to keystore location"
                      keystorePass="keystore password"
                      keyAlias="tomcat"
                      truststoreFile="path to trstustore location"
      truststorePass="truststore password"
      />

Ciphers: Usually there is a long list of ciphers you can list to be available (The first acceptable cipher found matching the ordered list of preferred ciphers from the client will be the one used)
ciphers="TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_RSA........."

Tomcat also accept the OpenSSL syntax for the list for ciphers e.g ciphers="HIGH:!aNULL:!RC4:!MD5:@STRENGTH" as above. By not naming ciphers explicitly it is easier to use the stronger ones automatically as new Tomcat & Java versions are released.

HTTPS Only

To have the Tomcat server to only accept HTTPS secure connections, put the following in the web.xml file:

<!-- Force HTTPS, required for HTTP redirect! -->
<security-constraint>
    <web-resource-collection>
        <web-resource-name>Protected Context</web-resource-name>
        <url-pattern>/*</url-pattern>
    </web-resource-collection>
    
    <!-- auth-constraint goes here if you require authentication -->
    <user-data-constraint>
        <transport-guarantee>CONFIDENTIAL</transport-guarantee>
    </user-data-constraint>
</security-constraint>

The configurations above will take effect once the Tomcat service is restarted. Now if you go to http://product.bmc.com, it will redirect to https://product.bmc.com.

NOTE: Check that no other process is using the TCP ports "80" and "443" on the system; you can run "netstat -ano" to see if the ports are used by another process.

Tomcat User for service/Process

Running the Tomcat Service/Process as a privileged user should be avoided, i.e. any user that has Administrator or Root permissions. Create a dedicated user to start the Tomcat service/process.

Windows

Create a user with "Log on as service". On the file system set the following permissions on the Tomcat Directory for the user "Modify", "Read & Excute", "List Folder Content", "Read" and "Write" as shown below:



Linux

For security purposes, if you're not using a package from the distribution itself, you will need to create a dedicated, non-root user "tomcat" who belongs to the "tomcat" group. From the shell:
sudo groupadd tomcat

sudo mkdir /opt/tomcat

sudo useradd -s /bin/nologin -g tomcat -d /opt/tomcat tomcat

This creates a user "tomcat" who belongs to the group "tomcat". You cannot use this user account to log into the system. The home directory is /opt/tomcat, which is where the Apache Tomcat program will reside (change the location to where you want to install Tomcat).

Tomcat Auto Deploy Feature

One feature Tomcat has out of the box is the ability to deploy .war files on startup. This should be disabled. Not only will this stop unauthorized applications from deploying, it will also make startup quicker.  If you are using Tomcat as a shared web server, ensure that no other application needs this auto deployment feature. Auto deployment can be turned off in the server.xml file:

<Host name="localhost"  appBase="webapps"
            unpackWARs="true" autoDeploy="false">

Tomcat Shutdown Port

Disable the tomcat shutdown port by setting the shutdown port value to "-1" in the server.xml file. This prevents malicious actors from shutting down Tomcat's web services.  If the port can not be disabled then set a strong password for shutdown. You can still shutdown tomcat directly on the server itself with the "-1" entry but not remotely:

e.g. Disable port
<Server port="-1" shutdown="SHUTDOWN">

e.g. Strong Password
<Server port="8005" shutdown="R3mot3-5hu!dOwN!\">

Connectors

By default Tomcat publishes two connector types: HTTP & AJP

non-TLS HTTP, on TCP port 8080
AJP Connector, on TCP port 8009

In most configurations Tomcat request/responses will go over HTTP/HTTPS.  The AJP connector is generally used for parsing requests through reverse proxies, although still slightly more efficient than HTTP over reverse proxies it's often not needed and should be disabled in the server.xml file.

From:
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />

To:
<!-- <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" /> -->


If you need to use the AJP connector, then it needs to be secured correctly with the following entries in the server.xml file:

From:

<!-- Define an AJP 1.3 Connector on port 8009 -->

<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />

To:

<!-- Define an AJP 1.3 Connector on port 8009 -->

<Connector port="8009" address="localhost" requiredSecret="true" secret="strong and unique password" protocol="AJP/1.3" redirectPort="8443" />

Clear Text Password In Server.xml file

This is yet another example of the chicken or the egg causality dilemma. Please refer to the Tomcat wiki for more information.

Ciphers

BMC recommends using only TLS 1.2 with strong ciphers.

In the server.xml file
Cipher Suites

<Connector
ciphers="TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,TLS_DHE_DSS_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_SHA256,TLS_ECDHE_RSA_WITH_AES_128_SHA,TLS_ECDHE_ECDSA_WITH_AES_128_SHA,TLS_ECDHE_RSA_WITH_AES_256_SHA384,TLS_ECDHE_ECDSA_WITH_AES_256_SHA384,TLS_ECDHE_RSA_WITH_AES_256_SHA,TLS_ECDHE_ECDSA_WITH_AES_256_SHA,TLS_DHE_RSA_WITH_AES_128_SHA256,TLS_DHE_RSA_WITH_AES_128_SHA,TLS_DHE_DSS_WITH_AES_128_SHA256,TLS_DHE_RSA_WITH_AES_256_SHA256,TLS_DHE_DSS_WITH_AES_256_SHA,TLS_DHE_RSA_WITH_AES_256_SHA"
/>


NOTE: To be able to use the 256 bit AES Ciphers, it is necessary to install the JCE Unlimited Strength Jurisdiction Policy Files.

Other Tomcat Configurations

Out of the Box the following tomcat parameters are disabled with Tomcat (version 8.0 ), its good to be aware of them in case you need to enable them for reasons of troubleshooting etc. be sure to disable them after. Most of these entries are configured in the server.xml file they are not there by default, you will have to specifically add them in.


Public facing stack traces - By default, Tomcat does not include any error page, so when hitting an exception in the application, it will display a stack trace to the requestor. While this is handy when developing an application, it should not be allowed in production since a stack trace leaks very useful bits of knowledge to an attacker. It is therefore recommended to add an error page, and configure Tomcat to use it.


Hide Tomcat version number from error pages - By default, Tomcat will display its version number on error pages, which may be considered as a leak of information, especially when running old versions. If you can't upgrade your Tomcat instance to the latest, here is how you can hide this sensitive information. 

Go to $CATALINA_HOME/lib, and create the  following directory structure: "org/apache/catalina/util". in the final "util" directory, create a file named "ServerInfo.properties", and set the "server.info" property to whatever string you want. For example: "server.info=Tomcat Version X". Restart tomcat.


Security headers - Those headers are X-Frame-Options (to prevent clickjacking attack), X-XSS-Protection (to avoid cross-site scripting attack), X-Content-Type-Options (block content type sniffing), and HSTS (add strict transport security). In Tomcat 8, edit the web.xml file of your application, and un-comment the "httpHeaderSecurity" filter section:

<filter>
    <filter-name>httpHeaderSecurity</filter-name>
    <filter-class>org.apache.catalina.filters.HttpHeaderSecurityFilter</filter-class>
    <async-supported>true</async-supported>
</filter>

<init-param>
    <param-name>hstsEnabled</param-name>
    <param-value>true</param-value>
</init-param>


That instructs Tomcat to support the security headers. Then add the following:

<filter-mapping>

    <filter-name>httpHeaderSecurity</filter-name>

    <url-pattern>/*</url-pattern>

</filter-mapping>

and restart Tomcat. This should allow Tomcat to add all the security headers to the responses it sends back to client requests.

Note: For more granular control, edit the specific attributes in the web.xml file. Refer to the Tomcat official documentation for more information.


HttpOnly and secure flag- Raise the bar against XSS! In the context.xml, protect your cookies by enabling HttpOnly: useHttpOnly="true", and in the server.xml set the secure flag with secure="true".

Note: This could be done in the server.xml too. The server.xml is for the Tomcat server, so the changes made here affects the entire server. The context.xml and web.xml pairs are per application, and any change in those files will apply to that specific application only.


allowTrace - The allowTrace attribute may be used to enable TRACE requests which can be useful for debugging. Due to the way some browsers handle the response from a TRACE request (which exposes the browser to an XSS attack), support for TRACE requests is disabled by default.

x-Powered-By  - The X-Powered-By attribute controls whether or not the X-Powered-By HTTP header is sent with each request. If sent, the value of the header contains the Servlet and JSP specification versions, the full Tomcat version (e.g. Apache Tomcat/8.0), the name of the JVM vendor and the version of the JVM. This header is disabled by default. This header can provide useful information to both legitimate clients and attackers.

SSL V2,V3 - SSLv2 and SSLv3 are inherently unsafe (Poodle Attack), there is no reason to have this protocol enabled. Search the server.xml file for enabled protocols "sslProtocol=" and remove it from the protocol list

deployXML - In a hosted environment where web applications may not be trusted, set the deployXML attribute to false to ignore any context.xml packaged with the web application that may try to assign increased privileges to the web application. Note that if the security manager is enabled that the deployXML attribute will default to false.

Listings - The DefaultServlet is configured with listings set to false. This isn't because allowing directory listings is considered unsafe but because generating listings of directories with thousands of files can consume significant CPU leading to a DOS attack.

DefaultServlet This applies to the default conf/web.xml file and WEB-INF/web.xml files in web applications if they define the components mentioned here.
The DefaultServlet is configured with read only set to true. Changing this to false allows clients to delete or modify static resources on the server and to upload new resources. This should not normally be changed without requiring authentication. The DefaultServlet is configured with listings set to false. This isn't because allowing directory listings is considered unsafe but because generating listings of directories with thousands of files can consume significant CPU leading to a DOS attack. The DefaultServlet is configured with showServerInfo set to true. When the directory listings is enabled the Tomcat version number is included in the response sent to clients. To avoid this, you can explicitly configure a DefaultServlet and set its showServerInfo attribute to false.


Additonal resources

There are plenty of useful resources on the internet when it comes to Tomcat hardening. Some references can be found here:

Reporting vulnerabilities

Customers should contact their Support team to report vulnerabilities or concerns about security.

Was this page helpful? Yes No Submitting... Thank you

Comments