Top tips for improving Tomcat web app security

Not every web app needs to be developed and configured as secure as a bank or a government's website. Most web apps just need to be "secure enough", where that term is defined by whoever runs the website, based on how secure they think it needs to be for the users to trust the website enough to use it. It's relative.

When you want to make your website more secure, it is important to have more than enough information about how to secure it, including how to secure it more than you need it secure. That way, you can choose which subsystems to improve security on and you have more than enough ideas and examples on how to do that.

In this article, we'll look at top ways to start investigating security for your Tomcat web application right away. As you read these items, keep in mind that the list is not exhaustive and that security is never one-size-fits-all. Some sites may require specialized security measures not included in this list, while others may require only some, not all, of the measures on this list. Investigate thoroughly, so that you know what's right for your site.

Top Tomcat webapp security tips

  1. Use HTTPS Only
  2. Distrust and sanitize all input from the client
  3. Identify and repair web app vulnerabilities for known exploits
  4. Filter for XSS


1. Use HTTPS only

HTTPS is the right tool for higher security, designed for keeping all application data confidential between the secure client and the secure server. Using unencrypted HTTP makes it much easier for a malicious user to send requests as another target user, opening your web application up to a wide variety of different injection attacks.

Using HTTPS eliminates the possibility of several whole classes of web app vulnerabilities and makes it generally more difficult to exploit a web site.

Configuring Tomcat HTTPS

Just configuring an additional HTTPS Connector in Tomcat is not enough to force all web clients to use HTTPS to access your website. You must either disable your other Connectors, or make your web app redirect all http:// requests to https:// URLs.

It is relatively easy to make your website require HTTPS. Add this security constraint to your web app's WEB-INF/web.xml file:




This tells Tomcat that your entire web app (all requests matching the pattern "/*", which is literally all requests) requires HTTPS. If there are some requests that you want to exclude from the HTTPS redirect, you can place those <url-pattern>s in the second <security-constraint> -- those requests won't be redirected to HTTPS, such as favicons (*.ico).

When Tomcat receives a request that matches the CONFIDENTIAL security constraint, Tomcat will redirect to the Connector's configured redirectPort for HTTPS. On your HTTP (unencrypted) Connector, make sure that the redirectPort attribute is set to your HTTPS port number.

Then, Tomcat will redirect insecure requests to your secure HTTPS Connector.

For more information about Tomcat SSL configuration, you can visit the HOW-TO provided by Apache, check out MuleSoft's guide to Tomcat SSL, or consult Chapter 6 of Tomcat: The Definitive Guide, an O'Reilly publication co-authored by Jason Brittain, lead architect of Tcat.


2. Distrust and sanitize all input from the client


Even when request data can arrive at the server only via HTTPS, a user can still send data to try to make your web app do things it wasn't designed to do. For instance, a malicious user could carefully craft and send a request to read one of Tomcat's config files, or to invoke a command on the server.

You should assume that any field of the HttpServletRequest can be set by the user. For increased security, run these strings through some validation/sanitization code before you store them anywhere, such as a database. The best practice for handling this is to use data validator code for every string that comes from the user. Make the string pass through the validator first. Then and only then, should you attempt to save or otherwise use the data.


Example code - Validate and replace code sanitization

As an example, let's assume that you don't want anyone to be able to include special characters such as '<' and '>' and quotation characters in requests, which might allow malicious content to be injected into your application. Filter code will enable you to search for and remove that data from the request, replacing any of those characters with their HTML entity equivalents.

Here's an example of how you might implement this kind of validation:


public static String filter(String value) {
if (value == null) {
return null;
StringBuilder result = new StringBuilder(value.length());
for (int i = 0; i < value.length(); ++i) {
switch (value.charAt(i)) {
case '<':
case '>':
case '"':
case '\'':
case '%':
case ';':
case '(':
case ')':
case '&':
case '+':
return result;
Validation Filter hosted with ❤ by GitHub


Passing user data through this method will convert any of these special characters into their (mostly harmless) HTML entity equivalents. If a malicious user is trying to carefully craft just the right markup to insert HTML tags into your web page, cleaning the input of special characters will make their job much more difficult. At the same time, when one of your normal users enters, say, a greater-than sign, '>', the HTML equivalent will still be displayed.

Another technique other than the translation method demonstrated above is to use code which intercepts a request and sends the user an error message when they type in characters that don't match the explicitly stated accepted characters. For example, if a username field can only be alphanumeric, requests containing characters outside of this set are not transmitted and the user is shown an error page or alert informing them of their illegal input.

When deciding what character sets you should accept, it's often most effective to work systematically, starting with the default alphanumeric set and then enabling only the additional sets required to make your web app user-friendly.

About HTML injection attacks

The logic behind using taking this systematic approach is that each additional special character you allow is one more possible tool for a malicious user to use against your site. Attacks of this type are known as "HTML Injection Attacks".

Here are some standard HTTP request fields that your web app and/or Tomcat will be reading

The standard HTTP requests read by your web app and/or Tomcat includes many hidden fields that the user is able to set to an arbitrary value. These fields include:

  • Header names
  • Header values
  • Cookie names
  • Cookie values
  • POST parameter names
  • POST parameter values
  • Path info
  • Query string
  • GET parameter names
  • GET parameter values
  • Request body
  • HTTP method name

Your web app may retrieve and use any of these strings from the request. If you do not validate and filter them for bad input, your web app may be exploited in some creative ways. While it is true that Tomcat makes an attempt to validate the input on the request values that it tries to use and/or parse, this does not mean that you can assume they will reach your web application without corruption. Validate and filter each of these before using them.

3. Scan for Web vulnerabilities and fix your web app's code


Finding security vulnerabilities in a web application is not simple - it's a highly specialized, tedious task, that requires knowledge of how to carry out the attacks and how exactly the attacks work. Even if they have an impeccable understanding of a web application's architecture from a white hat perspective, many web app developers don't have a full understanding of security exploits, nor do most administrators.

For this reason, many web apps vulnerabilities are left unlatched, even if the vulnerabilities are known within the security community. A recent survey found that 80% of all web applications are vulnerable to at least one known XSS or CSRF exploit, with a smaller percentage vulnerable to other more damaging known exploits such as Blind SQL Injection.

This state of affairs has made web applications a favorite target for hackers. In 2007, a Symantec study estimated that as many as 80% of all malicious traffic on the internet can be attributed to Cross-Site Scripting (XSS) and Cross-Site Request Forgery (CSRF) exploits against web applications.

If the expertise to discover these vulnerabilities is not available in-house, there are two approaches to performing the audit:

  1. Hire a web security firm or consultant to perform the discovery and analysis and give you a vulnerability report for your web app. This option is somewhat costly, but is likely to yield you good results, as long as the hired firm or consultant is knowledgeable and experienced. Choose your firm based on the quality of their prior work and the types of applications they are familiar with.
  2. Run some web security scanner software against your web app and have it generate a report. Both commercial and open source vulnerability scanners can be very effective, although you should be aware that these tools are not fully automatic. All of them, whether commercial or open source, take some significant time to install, understand and get running. However, this time investment is small when compared to the time it would take to learn about each type of vulnerability and how to detect it yourself.

It's important to remember that no matter what route you take, no single approach will fully protect your web app against vulnerabilities. Each scanning and discovery method or software you use will expose only a subset of your web app's vulnerabilities. You can only approach 'complete security'. Using a combination of software and consultants may yield better results than only going with one or the other.

A good security audit process looks something like this:

  • Perform a full, exhaustive HTTP security scan (this should take around one day to complete)
  • Generate a report showing which vulnerabilities were detected
  • Inspect the code for false positives
  • Verify that the non-false positives are real vulnerabilities
  • Make any necessary code modifications to remedy any verified vulnerabilities
  • Redeploy the code so that the changes take effect
  • Reinitialize the web app's database (if any) so that any data from a previous scan is cleared
  • Clear the scanning software and begin a new scan
  • Go back to the first step

Repeat this process and verify that the detected vulnerabilities decrease upon each iteration. If the code change you made to close a vulnerability still shows as being vulnerable in the next scan's report, inspect the report's HTTP request/response details and go back into the code to implement the fix and re-scan until the scanner no longer show it as being vulnerable.

Of course, you may also be able to exploit the vulnerability by hand between scans if the report shows you how (many do), so you know specifically how each exploit works and why the code was vulnerable.

Completing this process will result in dramatic improvements to your web app's security.

In Tomcat: The Definitive Guide, my co-author and I discuss and demonstrate the types of vulnerabilities I described above. See Chapter 6, Tomcat Security for those sections. Also, here are some links for definitions and further reading on these vulnerability types:

Cross Site Scripting (XSS)

Cross Site Request Forgery (XSRF)

SQL Injection

Code Injection / Command Injection


4. Filter for XSS


Cross-Site Scripting (XSS) vulnerabilities are arguably the most common type of vulnerabilities on the web today. There are many different varieties, varying in severity from a minor annoyance to major threat.

If your web app allows form submissions and/or allows users to log in and/or to type something into a web page, there is a very high likelihood that your web app has one or more XSS vulnerabilities.

In addition to plugging XSS vulnerability holes you find in your web app, another proactive measure you can take to help foil the attacks is to enable a filter that breaks known XSS exploits as the requests enter Tomcat.

This type of filtering changes the request data on the way in, before the data gets into the database (where it malicious input can spread) and before the exploit reaches any web app code that might be vulnerable (for example, a vulnerability missed by your security scan). With the prevention filter enabled, though, you break the exploit on the way in, regardless of which part of the web app's code it was destined for.

MuleSoft's Jason Brittain, co-author of the O'Reilly-published Tomcat: The Definitive Guide, includes a section in this book about foiling XSS exploit filtering, including demonstrations of Valve and Filter implementations capable of filtering malicious input. These implementations have now been made open source as the Catnip project, available for download at

Enabling this filter in your Tomcat or as part of your web app will further increase security and also give you a configurable global filter where you can add your own regular expressions to filter out any user input you'd like.