javaxssfortifycross-siteesapi

ESAPI for XSS prevention not working


I am working on fixing Cross site scripting issues in our code mainly in JSPS.

Below is the original code

 //scriplet code
    <% String userId = request.getParameter("sid"); 
    ...%>

and in the same Jsp they have

     <input type = hidden name = "userID" value = "<%= userId %>" />

I have made changes to include esapi-2.1.0.jar in lib and ESAPI.properties, validation.properties in classpath. Then made below changes to scriplet code to fix the above code

      //scriplet code
    <% String userId = ESAPI.encoder().encodeForHTML(request.getParameter("sid")); 
    ...%>

I thought this would fix the issue but when I scan my code using Fortify, these lines are again highlighted as having XSS issue. Please help if you guys have any idea on how this should be handled. Thanks.

------- UPDATE

Thanks a lot @avgvstvs. This is very insightful.Follwd guidelines, Not sure if I am missng somethn. Code -

          String              userSID=ESAPI.encoder().encodeForHTMLAttribute(request.getHeader("janus_sid")); session.setAttribute("username",userSID);<input type=hidden name="USERNAME" value="<%= userSID %>"

And for another varibale debug, below is the usage

       String debugFlag =  ESAPI.encoder().encodeForJavaScript(request.getParameter("debug"));var debugFlag = "<%= debugFlag%>";if(debugFlag == "y"){       
        document.title=   title + " (" + host + ")";
        defaultAppTitle = title + " (" + host +  ")";           
    }                                                           

Latest Fortify scan still lists them as vulnerabilities :-(


Solution

  • Thanks for help guys. Finally figured out a solution to prevent XSS issue and pass Fortify static code analysis. I have used ESAPI together with Anitsamy library. Here are the 3 main changes required.

    1. Implement Anitsamy Filter

      Add a new filter and override request methods getParameter , getParameterValues to strip out any suspicious tags in the request. Filter loads a policy file where we define our rules like

      a. tags which needs to be removed from the requests ( tags like , etc)

      b. Regexs for common attributes like href, align etc.

    Example for implementation of filter is here http://barrypitman.com/2011/04/14/using-input-validation-XSS/

    1. Perform input validation using ESAPI library

       String reportName = request.getParameter("reportName");
       ESAPI.validator().getValidInput("Report Name", 
                                        reportName, "ReportNamePattern", 100, false);
      

      In above code,

      1. "Report Name" is the context
      2. reportName is the data field
      3. ReportNamePattern is the regex pattern defined in ESAPI.properties as Validator.ReportNamePattern =^[a-zA-Z]{1}[0-9]{6}$
      4. 100 is max length for data field reportName
      5. false is a flag to say null value is not allowed.
    2. Perform output encoding
      As pointed by @avgvstvs, output encoding is also a must.

      If reportName field is to be used in HTML, below is how to encode

      <tr> <th> Report :     <%=ESAPI.encoder().encodeForHTML(reportName)%> </th> </tr>
      

      If reportName field is to be used in javascript code , below is how to encode

       var reportName = "<%= ESAPI.encoder().encodeForJavaScript(reportName)%>";
      

      If reportName field is to be used in HTML Attribute, below is how to encode

      <input type=hidden name="USERNAME" value="<%=ESAPI.encoder().encodeForHTMLAttribute
          (reportName)%>"/>