Skip to main content
Skip table of contents

Harden Tomcat

This article describes how to harden your Tomcat installation. The examples applies to Apache Tomcat 8.x. 

Step-by-step instructions

Add Rate limit filter to prevent DoS Attacks

Tomcat version 9.0.76 or higher is required to support the Rate limit filter. The filter can be used for older Prime/Identity Manager versions as well if Tomcat is updated to a supported version.

To prevent "Denial of Service" (DoS) attacks, a "Rate limit filter" can be added to web.xml in the Tomcat installation.

In Smart ID Docker containers it will be added automatically.

The filter can be added to web.xml for each application if adjusting the settings individually is needed, instead of having a global setting valid for all applications. However, it is easier to maintain in one location.

  1. Configure the filter in Tomcat/conf/web.xml. See an example below:

Example: Rate limit filter
CODE
 <!-- Filter to prevent Denial of Service (DoS) and Brute Force attacks by limiting
 the number of requests that are allowed from a single IP address
 during a certain time span (time bucket) -->
<filter>
  <filter-name>RateLimitFilter global</filter-name>
  <filter-class>org.apache.catalina.filters.RateLimitFilter</filter-class>
  <init-param>
    <!-- The number of requests that are allowed in a time bucket. Default is 300. -->
    <param-name>bucketRequests</param-name>
    <param-value>200</param-value>
  </init-param>
  <init-param>
    <!-- The number of seconds in a time bucket. Default is 60. -->
    <param-name>bucketDuration</param-name>
    <param-value>60</param-value>
  </init-param>
</filter>
<filter-mapping>
  <filter-name>RateLimitFilter global</filter-name>
  <url-pattern>*</url-pattern>
</filter-mapping>
Remove server banner
  1. Go to the $tomcat/conf folder

  2. Modify server.xml by using a text editor.

  3. Add the following to Connector port:

    CODE
    Server =" "

    Example:

    Example: Remove server banner

    CODE
    <Connector port="8080" protocol="HTTP/1.1"connectionTimeout="20000"
    Server =" "
    redirectPort="8443" />
Enable TLS/SSL

To enable TLS/SSL, add a connector for port 443 to the Tomcat configuration:

  1. Go to the $tomcat/conf folder

  2. Modify server.xml by using a text editor.

  3. Add the following content:

    CODE
    <Connector port="443"
                    protocol="org.apache.coyote.http11.Http11Protocol"
                    Server=" "
                    SSLEnabled="true"
                    maxPostSize="-1"
                    maxThreads="800"
                    minSpareThreads="80"
                    maxSpareThreads="160"
                    disableUploadTimeout="true"
                    scheme="https"
                    secure="true"
                    clientAuth="false"
                    keystoreFile="/opt/tomcat/cert/myssl.p12"
                    keystorePass="<secretpassword>"
                    keystoreType="PKCS12"
                    truststoreFile="/opt/tomcat/cert/castore.jks"
                    truststorePass="<secretpassword>"
                    truststoreType="JKS"
                    sslProtocol="TLS"
                    sslEnabledProtocols="TLSv1.2"
                    useServerCipherSuitesOrder="true"
                    ciphers="TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
                            TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,         
                            TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
                            TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,         
                            TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,           
                            TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,
                            TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"
    />

For more information, see https://tomcat.apache.org/tomcat-9.0-doc/ssl-howto.html

Enforce HTTPS

Even if you have an http connector, for example in port 8080, it will redirect to the configured ssl port. To enforce HTTPS, do the following:

  1. Go to the $tomcat/conf folder

  2. Modify web.xml with a text editor.

  3. Add the following before the </web-app> syntax:

    CODE
    <security-constraint>
        <web-resource-collection>
        <web-resource-name>Protected Context</web-resource-name>
        <url-pattern>/*</url-pattern>
        </web-resource-collection>
        <user-data-constraint>
            <transport-guarantee>CONFIDENTIAL</transport-guarantee>
        </user-data-constraint>
    </security-constraint>
Add Secure & HttpOnly flag to cookie

It is possible to steal or manipulate web application session and cookies without having a secure cookie. Here "secure" is a flag which is injected in the response header.

  1. Add this line in the session-config section of the web.xml file:

    CODE
    <cookie-config>    
        <http-only>true</http-only>
        <secure>true</secure>
    </cookie-config>
Run Tomcat from non-privileged account

This is valid for Linux- and Unix-like operating systems.

To lower the impact of a potential attack, it is recommended to run Tomcat with a non-privileged user. Follow these steps to add a non-privileged user and run Tomcat with that user:

  1. Create a group called tomcat.

  2. Add a user called tomcat to the tomcat group, with the following attributes:

    1. Set the home directory to /opt/tomcat. This directory is where Tomcat is installed.

    2. Set the shell to /bin/nologin (so that nobody can log into the account).

  3. Start Tomcat as the new tomcat user.

    Linux example: add tomcat group and user

    CODE
    # Preparation
    sudo groupadd tomcat
    sudo useradd -M -s /bin/nologin -g tomcat -d /opt/tomcat tomcat
    sudo chgrp -R tomcat /opt/tomcat
    sudo chmod -R g+r conf
    sudo chmod g+x conf
    sudo chown -R tomcat webapps/ work/ temp/ logs/ cert/
     
    # Startup as tomcat user
    sudo su -c /opt/tomcat/bin/startup.sh - tomcat
Remove default/unwanted applications

By default, Tomcat comes with the following web applications, which may be required in a production environment. You can delete them to keep it clean and avoid any known security risk with Tomcat default application.

  • ROOT – Default welcome page

  • Docs – Tomcat documentation

  • Examples – JSP and servlets for demonstration

  • Manager, host-manager – Tomcat administration

They are available under the $tomcat/webapps folder.

Change SHUTDOWN port and command

By default, Tomcat is configured to be shutdown via port 8005. Tomcat can then be shut down by opening telnet to IP:port and issuing the SHUTDOWN command.

It’s recommended to change the Tomcat shutdown port and default command to something unpredictable.

  • Modify the following in server.xml:

    CODE
    <Server port="8005" shutdown="<complicatedpassword>">
  • Or disable the shutdown port completely:

    CODE
    <Server port="-1" shutdown="SHUTDOWN">
Replace default 404, 403, 500 page

If you have the default pages for not found (404), forbidden (403), and server error (5xx), this will expose version details.

To mitigate this:

  1. Create a general error page:

    1. Go to the $tomcat/webapps/$application.

    2. Create an error.jsp file using a text editor.

      Example

      CODE
      <html>
          <head>
              <title>Error Page</title>
          </head>
          <body> That's an error! </body>
      </html>
  2. Configure web.xml to redirect to the general error page.

    1. Go to the $tomcat/conf folder.

    2. Add the following in the web.xml file before the </web-app> syntax:

      CODE
      <error-page>
          <error-code>404</error-code>
          <location>/error.jsp</location>
      </error-page>
      <error-page>
          <error-code>403</error-code>
          <location>/error.jsp</location>
      </error-page>
      <error-page>
          <error-code>500</error-code>
          <location>/error.jsp</location>
      </error-page>


  3. You can also do the same for java.lang.Exception. This will help in not exposing the Tomcat version information if any such error happens. Add the following in web.xml and restart the tomcat server:

    CODE
    <error-page>
        <exception-type>java.lang.Exception</exception-type>
        <location>/error.jsp</location>
    </error-page>
Restrict application to specific IP address or network

If you don't want Identity Manager Admin or Identity Manager Tenant to be accessible over the internet, this is an example of how you can restrict access per application in Tomcat.

  1. Modify  $tomcat/webapps/$application/META-INF/context.xml
    This will allow access from IPV4 localhost, IPV6 localhost, any IP that begins with 10 and also from the public IP of the Nexus Stockholm Office.

    CODE
    <context>
        <Valve className="org.apache.catalina.valves.RemoteAddrValve"
            allow="127\.\d+\.\d+\.\d+|10\.\d+\.\d+\.\d+|83\.\241\.\229\.\132|::1|0:0:0:0:0:0:0:1" />
    </context>
  2. Restart Tomcat for changes to apply.

Hide Exception stack trace in error page

If you want to hide the stack trace thrown by Tomcat (Application Server) when something goes wrong or there is an error in some configuration file then this is an example of how you can restrict display of error stack trace.

  1. To hide the tomcat stack trace add the following lines to the host section of your server.xml file under <apche-tomcat>\conf  where you should already have the AccessLogValve:

    Modify  $tomcat/conf /server.xml

    CODE
    <Valve className="org.apache.catalina.valves.ErrorReportValve" showReport="false" showServerInfo="false"/> 

    Disabling both showServerInfo and showReport will now only return the HTTP status code.

  2. Restart Tomcat for changes to apply.

JavaScript errors detected

Please note, these errors can depend on your browser setup.

If this problem persists, please contact our support.