Brittain’s Tomcat BadInputFilterValve
Thanks to Jason Brittain for the BadInputFilterValve in his coauthored Tomcat book.
Here is a modified version that runs under Tomcat 5.5.12 (and hopefully 5.5.17, which is where I’m headed) without the need for Jakarta Regexp.
To activate copy the class to $CATALINA_HOME/server/classes and put this context.xml in your war’s META-INF directory:
<Context> <Valve className="org.carpediem.crm.BadInputFilterValve" deny="\\x00,\\x04,\\x08,\\x0a,\\x0d"/> </Context>
While I have not tested it extensively, my version appears to do no harm as an intermediary along the call chain pipeline – not much of a guarantee, I know, but it’s a start.
catalina.jar, catalina-optional.jar, servlet-api.jar, commons-logging-api.jar all need to be on your compile classpath.
[tags]tomcat,valves[/tags]
Hello Mark!
I’m glad you like my BadInputFilterValve (which was somewhat badly named, since something is really either a Tomcat Valve, or a webapp Filter — two different things — however it filters bad input, so I had a hard time naming it something that wasn’t confusing)!
Thanks for porting it to Tomcat 5.5. I already have a copy that was ported to 5.5 by someone else, but yours is slightly different, so it’s interesting to see.
I wanted to tell you that some other readers noticed a bug in the code that is easy to fix. The bug could be exploited as a denial of service attack, so you should modify yours to fix it. Near the bottom of the valve class, near the end of the filterParameters() method,
there is code that looks like this:
values[i] = newValue;
request.addParameter(name, values);
log(”Parameter \”" + name + “\”’s value \”" +
value + “\” matched pattern \”" +
pattern + “\”. Remote addr: ” +
((HttpServletRequest)
request).getRemoteAddr());
To fix it, remove the “request.addParameter(name, values);” line.
That’s it. The behavior should be *exactly* the same,
minus the potential for denial of service. In fact,
it should run a little faster, which is great.
Cheers.
–
Jason
Jason Brittain
October 20, 2006 at 12:28 am
Oh, also, back when I wrote it initially (2002?) I had the option of using one of three different regular expression parsers. The built-in Java regex engine, org.apache.regexp, and the ORO one. Each of them would have sufficed (albeit each with some limitations that I could work around), but, I ended up benchmarking each of them with the regular expressions I was using, and I found that the org.apache.regexp engine was the fastest. I decided to use that one since security was number one, but performance was number two, and since they all would have worked, number one was already taken care of.
I noticed that when you refactored the Valve for Tomcat 5.5, you also made it use the built-in Java regex engine. At least back when I first wrote the valve, that was by far the slowest regex engine out of the three I tested, mainly because it generated quiet a bit of Object garbage in comparison to the others. I have not benchmarked them since then, and things could have changed since then, but I’d bet they’ve just about all improved in that time.
Just so you know.
–
Jason
Jason Brittain
October 20, 2006 at 12:38 am
Jason, hello, and thanks for the followup.
I have modified the posted code.
Thanks for the great book on Tomcat, too. I’ve read every page, several times. Your chapter on chrooting Tomcat has been very helpful.
Mark
ae6rt
October 20, 2006 at 5:57 am
I have successfully applied this to my jboss server too.
However, IMO there is still a gap: When the parameter is directly entered in the URL (http://localhost:8080/accessories?filter_brand=%3Cscript%3Ealert(‘xss’)%3C/script%3E), the valve does not intercept it and the javascript code is still executed.
Eric Tchepannou
August 9, 2007 at 1:23 am