Thursday, 4 June 2009

JSP EL , Spring MVC and XSS

I'm trying to find the exact behavior of JSPs EL on Spring MVC apps (also posted on the java-project@lists.owasp.org mailing list)

Here a sample code that shows the workflow:

-------------
on a controller class (marked with the @Controller attribute)

@RequestMapping(value = "/externalUrl.html", method = RequestMethod.GET)
public String doSomething(HttpServletRequest request, Map model) {
model.put("putPayloadHere", request.getParameter("putPayloadHere"));

return "viewThatShowsPayload";
}

on the JSP (for example /jsps/viewThatShowsPayload.jsp)


payload: ${putPayloadHere}


-------------
for reference the above code will be compiled (in the viewThatShowsPayload_jsp.java) into something that looks like this:

out.write("");
out.write((java.lang.String) org.apache.jasper.runtime.PageContextImpl.proprietaryEvaluate("${putPayloadHere}", java.lang.String.class, (PageContext)_jspx_page_context, NULL, false));
out.write("");


My question is: In the above example will the request http://xxx/externalUrl.htm?putPayloadHere= ALWAYS result in XSS?

The key part of the question is the always bit, since:

a) By default (according my google searches) ${xxx} in JSP doesn't perform HTML Encoding (the sugested alternative is (which does HTML Encode by default (see http://www.sleberknight.com/blog/sleberkn/entry/20060721 (2006 post) )

b) in Spring MVC there is the DefaultHtmlEncode option (http://static.springframework.org/spring/docs/2.5.x/reference/spring.tld.html#spring.tld.htmlEscape), but this only seems to affect the Spring Tags. I belive this is now enabled by default, but couldn't find any documentation to support that (http://shh.thathost.com/secadv/spring-form-xss/)

c) Are there other valid alternatives to make ${xxx} encode its result by default? For example Matt Raible in http://raibledesigns.com/rd/entry/java_web_frameworks_and_xss mentions this: "The good news is #2 doesn't seem to be that hard. I pulled down commons-el yesterday, added a hack to escape XML, re-jarred and put it in Tomcat 5.0.25's classpath. This actually worked and I was impressed it was so easy. However, when I looked at Tomcat 6, commons-el is no longer used and now there's a "jasper-el.jar" in the lib directory. I don't mind modifying another library, but what's the difference between jasper-el and commons-el? " , have anybody seen this solution work on an enterprise app?

d) Matt also triggered this request http://raibledesigns.com/rd/entry/proposed_tomcat_enhancement_add_flag which doesn't seem to have gone anywhere, should this be something that the ISWG should be persuing?

e) Finally, is there an equivalent for J2EE of the Microsoft Anti-XSS (the latest version) which is able to add output encoding without touching the code?

(note: I also looked at http://www.owasp.org/index.php/JSP_JSTL and http://www.owasp.org/index.php/J2EE_Bad_Practices:_JSP_Expressions and once I've clarify this, will update these pages with the results)