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 :-(
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.
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/
Perform input validation using ESAPI library
String reportName = request.getParameter("reportName");
ESAPI.validator().getValidInput("Report Name",
reportName, "ReportNamePattern", 100, false);
In above code,
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)%>"/>