Using ESAPI to fix XSS in your Java code

Customized validation routines are the norm in Indian organizations for fixing vulnerabilities. OWASP’s ESAPI framework may prove to be a better option.

Indian organizations employ several security practices at each stages of the software development lifecycle (SDLC). This includes the use of server hardening, security guidelines and automated tools to detect potential vulnerabilities.

While this methodology is same for all companies, the process of providing a fix to the actual vulnerability differs. Native application programming interfaces (API) validate only simple input types. For complex and varied input, the Indian corporate typically relies on customized validation routines. Although these routines offer a quick fix to the identified vulnerability, it’s not really clear whether it will handle complex attacks.

This is when one seeks out a security standard that is approved for use globally. Such a popular framework is the OWASP Enterprise Security API (ESAPI). This API has a built-in validation framework, and provides standard security controls to write lower risk applications.

In this tutorial, we will discuss ESAPI, along with an example to show how you can fix an XSS vulnerability in a Java code-base. This tutorial is intended for developers who have a basic knowledge on XSS, but needs help to fix it.

ESAPI basics

OWASP defines ESAPI as a free, open source, Web application security control that makes it easier for programmers to write low-risk applications. All versions of ESAPI have the same basic design.

  • A set of security control interfaces.
  • A reference implementation for each security control.
  • Provision for optional customized implementation.

This design will help an Indian organization re-use the implementations for the common security controls provided by ESAPI. It will help the company add its own ad-hoc cases. Let’s move on to our actual example.

Problem statement

Assume that the application has the following code in a jsp page. An untrusted input is got from query-string, and is displayed to the user on a screen.




      String safeOutput = request.getParameter(“comment”);


      Output is <input type=”text” value=”<%=safeOutput %>” />




Imagine what will happen if the input ‘comment’ gets an input like “<script>alert(document.cookie); </script>”. This input looks harmless, but when loaded, can reveal the application cookie. A sample screenshot is shown below.

A security assessment tool (say Fortify) when run on this code will identify a potentially high XSS vulnerability.


Solution 1:

Let’s look at a customized fix now.


import org.apache.commons.lang.StringEscapeUtils;


      String input = request.getParameter(“comment”);      
String safeOuput = StringEscapeUtils.escapeXml(input);

      Output is <input type=”text” value=”<%=safeOutput %>” />




This function (escapeXML()) escapes certain characters using XML entities (>,<,”,&,’). Once validated, the developer runs Fortify again, and it recognizes escapeXML() as an output-encoding routine. The potential HIGH vulnerability is now remediated, and the developer moves this code to production. It seems that the problem is fixed, but this is not the end of the story.

Fortify actually recognizes escapeXML() as a weak output encoding routine, and highlights XSS vulnerability in low severity. So, what does Fortify actually mean when it says that escapeXML() is weak?

Assume that the blackhat hacker now tries to inject the code ‘” onLoad=alert(document.cookie); <input type=”’.

This string now passes through the ‘comment’ variable. EscapeXML() is applied to this variable, but since this does not have the five malicious characters, it lets the input pass through. So, the result is that the attacker still manages to steal the cookie.  The screenshot is as shown below.



In both the instances, the attack vector was different. However, the blackhat got his data. Now it will be clear that escapeXML() will not fix all XSS issues. So what should be ideally done in this situation? That’s when a standard framework gets in to the picture.

Solution 2:

The ESAPI approach to this issue is shown below.


import org.apache.commons.lang.StringEscapeUtils;



      String input = request.getParameter(“comment”);

      String Comment = ESAPI.validator().getValidInput("comment", input, "CommentRegex", 400, false, errorV);

      String safeOutput = ESAPI.encoder().encodeForHTML( Comment );    


Output is <input type=”text” value=”<%=safeOutput %>” />




Two types of validation are used here.

  1. Input validation
  2. Output validation

Input validation is used to ensure that only whitelisted input is accepted. In this case, a regex is defined to accept only known good characters that are suitable for use in a comments field. This is applied to the ESAPI’s validator API getValidInput().

Output validation is accomplished by ESAPI’s encoder API called encodeForHtml(). Now, untrusted input is safe to be printed in HTML. You will notice how I am cautious while saying that this is safe to be printed to a HTML entity.  What if the output needs to be printed to a URL or inside javascript? ESAPI’s encoding routines have built-in functionalities for every possible output.

When a Fortify scan is run on this code, Fortify recognizes that both input and output validations are in-place. This fixes the XSS vulnerability.

Now, the good news is that, ESAPI not only fixes XSS, but is aimed to be a security strategic refit in the application architecture. With ESAPI, companies can now be rest assured about security in their applications. This is not just a real fix, but also an excellent security practice to be incorporated in every application’s code base.


About the author: Celia Rexselin Aloysius has been with Infosys for the past five years, and associated with Internet Application Security since 2010. Her expertise includes product development, penetration testing and secure code analysis. Celia is a certified ethical hacker who is currently engaged in application security consulting. Her earlier assignments include active product development and service based offerings.

This was last published in November 2012

Read more on Application security and coding requirements

Join the conversation

1 comment

Send me notifications when other members comment.

Please create a username to comment.

I tried the code but I found some problems:
type Exception report


description The server encountered an internal error () that prevented it from fulfilling this request.


org.apache.jasper.JasperException: Unable to compile class for JSP

An error occurred at line: 15 in the jsp file: /crosstab.jsp
Generated servlet error:
Syntax error on token "import", assert expected


note The full stack trace of the root cause is available in the Apache Tomcat/5.5.7 logs.






  • How do I size a UPS unit?

    Your data center UPS sizing needs are dependent on a variety of factors. Develop configurations and determine the estimated UPS ...

  • How to enhance FTP server security

    If you still use FTP servers in your organization, use IP address whitelists, login restrictions and data encryption -- and just ...

  • 3 ways to approach cloud bursting

    With different cloud bursting techniques and tools from Amazon, Zerto, VMware and Oracle, admins can bolster cloud connections ...