Proposed Tomcat Enhancement: Add flag to escape JSP's EL by default

I posted the following to the Tomcat Developers mailing list. Unfortunately, it didn't get any responses, which means (to me) that no one cares about this feature. I guess the good thing is they didn't veto it.

Hello all,

I'm working for a client that's using a proprietary Servlet/JSP-based framework that runs on Tomcat. They have their own custom JSP compiler and they're looking to move to a standard JSP compiler. One of the things their compiler supports is automatic escaping of XML in expressions. For example, ${foo} would be escaped so <body> -> &lt;body&gt;. JSP EL does not do this. It *doesn't* escape by default and instead requires you to wrap your expressions with <c:out/> if you want escaping.

I'd like to ask what developers think about adding a flag (similar to trimSpaces in conf/web.xml) that allows users to change the escaping behavior from false to true?

I think this is a good option to have as it allows security-conscious organizations to paranoid and escape all content by default.

Thanks,

Matt

Related: http://raibledesigns.com/rd/entry/java_web_frameworks_and_xss

What do you think? Is there anything wrong with adding this (optional) feature to Tomcat? Enhancing security is a good thing - right?

Update: I've entered an enhancement request for this feature and attached a patch.

Posted in Java at Sep 19 2007, 04:29:11 PM MDT 12 Comments
Comments:

My understanding was that if you want text escaped you should use <c:out/> if you don't want it escaped you should use the el expression.

I can think of two reasons for not escaping:

  • I have had times where I am generating part of a javascript argument etc where I wanted < etc symbols retained. Escaping would break the javascript.
  • Performance, don't perform the escaping procedure for fields that are known not to require escaping (not sure how much of a difference this would actually make).

A tomcat specific extension sounds dangerous, you develop your app on tomcat and everything is secure. Then for some reason you switch containers (to say resin or jetty), your application is instantly no longer secure. I would prefer my applications to work securely in any container.

Posted by Richard on September 19, 2007 at 05:03 PM MDT #

> A tomcat specific extension sounds dangerous, you develop your app on tomcat and everything is secure. Then for some reason you switch containers (to say resin or jetty), your application is instantly no longer secure.

I agree, but I think it's easier to pursue this as an enhancement to Tomcat rather than as an addition to a JSR that takes 2 years to get approved and implemented. My logic is based on the fact that Tomcat had trim spaces quite a bit before it was part of a spec. Also, if it's optional and is only turned on by companies that know what they're doing - what harm is there?

I agree that <c:out> could be used, but this particular client is paranoid that developers will forget to use it all the time and some regular ${...} expressions will slip through the cracks. The only other options I can think of are 1) write some tool that parses JSPs and looks for standalone expressions and fails the build when they're found 2) use something like FreeMarker, which doesn't have very IDE tools and code completion.

The implementation I'm hoping to see/write would not affect the behavior of <c:out> - only standalone EL expressions.

Posted by Matt Raible on September 19, 2007 at 11:08 PM MDT #

We've had a similar problem with JSP and XML. Since we run the output of our JSPs through an XSL transformation the output must of course be 100% XML. We didn't want to use c:out all over the place and since we're using the XML syntax for our JSPs we cannot use c:out in attributes.

Our somewhat hacky solution is to preprocess all JSP files the first time they are used. This is done using a Filter which intercepts all includes/forwards for *.jsp files. The original JSP file is run through an XSL which modifies EL expressions in the JSP. ${foo} becomes ${escapeXml(foo)}.

I know it ain't pretty but at least it works! :-) Obviously this won't work if you aren't using the JSP XML syntax.

Posted by Niklas Therning on September 20, 2007 at 03:46 AM MDT #

Niklas - any chance you want to share that filter? ;-)

Posted by Matt Raible on September 20, 2007 at 07:55 AM MDT #

I would be more than happy to share the code. I've just blogged about how we did this and you will be able to download the code on my blog. Just let me know if you have any question about it or if I've done some stupid mistake. :-)

Posted by Niklas Therning on September 20, 2007 at 09:37 AM MDT #

I needed to add special behavior to EL, and it didn't turn out too hard to do so. The parsing system is all javacc based, and it was pretty easy to substitute my own classes in place of the standard behavior. (Eventually, we went a step further and introduced a factory.) If they can write their own JSP compiler, they can certainly do that. Or, if the objective is to get onto a standard servlet container, well, time to send all their JSPs offshore to have someone <c:out /> it all.

Posted by Trenton on September 20, 2007 at 11:29 PM MDT #

Trenton - how do you handle your custom modifications? Is jasper-el configurable or are you maintaining your own version?

Posted by Matt Raible on September 24, 2007 at 12:21 PM MDT #

Did this ever end up going anywhere? I am confronted with the same issue as Niklas and I cannot use c:out because my EL expression is doing a little processing like deciding to print the S after a plural value. Sometimes there are quotes involved and they are getting very screwed up with the HTML. Any help would be great. Thanks

Posted by John Paul on March 26, 2009 at 12:25 PM MDT #

@John - the issue is still open, so I'd say this still hasn't gone anywhere.

Posted by Matt Raible on March 26, 2009 at 12:41 PM MDT #

Matt, i'm absolutely agree with you! One of reason why java is useful is security and reliability. But nonescaped EL - is a hole. The best security politic is ban all except authorized. There is should be to posible to make a global html-escaping for ${ value }, except some one (for example, by define el-html-escaping regions)

Posted by Marat on December 10, 2009 at 01:21 AM MST #

So I realize I'm very late to this party, but I thought I'd add my two bits anyhow. I created a simple EL function to replace c:out. So I've replaced <c:out value='${some.property}'/> with ${s:esc(some.property)}. While not a proper solution, it is at least less verbose and more friendly to use in HTML attributes.

Code can be found here.

I'd still agree that escape-by-default would be better (and then have a tag or function for the rarer scenarios where you _don't_ want escaping.) Secure by default, right? But I didn't really want to patch libraries, so I thought this band-aid is better than nothing.

Posted by Thom Nichols on March 19, 2010 at 02:03 PM MDT #

[Trackback] Way back in 2007, I wrote about Java Web Frameworks and XSS . My main point was that JSP EL doesn't bother to handle XSS . Of course, the whole problem with JSP EL could be solved if Tomcat (and other containers) would allow a flag to turn on X...

Posted by Raible Designs on February 28, 2011 at 03:14 PM MST #

Post a Comment:
  • HTML Syntax: Allowed