Simple Cross Site Scripting (XSS) Servlet Filter
Ran into some issues on some of our Java sites today and needed a quick fix to protect the sites from malicious Cross Site Scripting (XSS) attempts. If you’re not aware of what XSS is and have websites that have sensitive user data, you may want to read up, you’re probably vulnerable, which means your users are vulnerable. I’m not claiming this is a perfect solution, but it was easy to implement and corrected the vulnerabilities with form and url injection. We basically have a Servlet Filter that’s going to intercept every request sent to the web application and then we use an HttpServletRequestWrapper to wrap and override the getParameter methods and clean any potential script injection.
Here’s the Filter:
package com.greatwebguy.filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
public class CrossScriptingFilter implements Filter {
public void init(FilterConfig filterConfig) throws ServletException {
this.filterConfig = filterConfig;
}
public void destroy() {
this.filterConfig = null;
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
chain.doFilter(new RequestWrapper((HttpServletRequest) request), response);
}
}
Here’s the wrapper:
There’s a space in the entity character of the cleanXSS method above, you’ll need to remove it if you copy the code above, or you can copy this plain text copy of the method to get the correct syntax.
Add this to the top of your web.xml:
XSS
XSS
com.greatwebguy.filter.CrossScriptingFilter
XSS
/*
I’m sure the cleanXSS replacements aren’t the most efficient way of doing this, you could replace it StringEscapeUtils.escapeHtml from commons lang to simplify it a little, it’s up to you, it all depends on what your site is doing and whether it’s going to be a pain having all the html escaped, you could also adjust the url-pattern of the filter to be more specific to your application urls, so that everything under your app isn’t running through the filter.
Some things to be aware of with this approach, you’ll need to account for what you’ve encoded or in some cases you’ll end up with weird characters in your database and possibly in validation of your input boxes. Some would recommend a more positive validation rather than negative validation and only allow a certain range of characters, it’s up to you, but it is something to think about.
about 2 years ago
Hi, you should really reformat you source in your posting , otherwise it really looks like nonsense:
value.replaceAll(“<”, “<”)
about 2 years ago
Yeah, thanks had some issue with Wordpress reformatting the text, I see the one you posted above looks great too. If you had read the post you would have found the link below the source posting with a text version of the cleanXSS method. http://greatwebguy.com/wp-content/uploads/cleanXSS.txt
about 1 year ago
Hi,
Am I missing something, or is the class variable this.filterConfig not initialized?
Eclipse complains, and simply initializing a class variable fixes it:
FilterConfig filterConfig = null;
Thx,
Bill
about 1 year ago
I think by implementing Filter it has to be part of init’s signature, if you’re not using it to pass in parameters into the filter there’s probably no reason to have anything in the init method.
about 1 year ago
Hi,
Tried the filter. It caught all the input form fields but not some of the parameters as “p_p_mode” sent in the URL? Still found XSS on those parameters.
Do not understand why. Any suggestions on how to fix?
Thanks,
about 1 year ago
hi can you please4 explain the meaning of each line in method private String cleanXSS(String value).. i mean which line is used to prevent what.
about 1 year ago
I’m getting this error on my jsps after I’ve implemented this filter. Any idea what causes this?
[12/10/08 12:38:43:289 EST] 0000003e ServletWrappe E SRVE0068E: Uncaught exception thrown in one of the service methods of the servlet: /welcome.jsp. Exception thrown : javax.servlet.ServletException: non-HTTP request or response
about 1 year ago
Hi, to be shure there is no evil code in the Request the URLEncoder-Output has to be checked too: %3Cscript%3Ealert%281234%29%3C%2Fscript%3E
about 11 months ago
Since line 45 replaces parathesis, line 47 will never be hit. Also, replacing all the JS events (onload, onclick, etc) is a good idea, as is making the match case insensitive.
about 11 months ago
Hi
I am interested in XSS and XSRF for protecting our servers.
I’m glad to refer your XSS Filter.
If input characters is “SCRIPT” or “ScRipT”, what should we do about line 49?
about 11 months ago
I think the main idea here is the use of a Servlet Filter to override the getParameter methods of the HttpServletRequest with an HttpServletRequestWrapper, the cleanXSS method I’m sure is not perfect, but is welcome to improvement, you could use a more complex regex to make it case insensitive to fix the “SCript” condition
about 11 months ago
Adding (?i) , in front of the replacing String would treat it as case insensitive way of replacement. So , in cleanXSS() method , you can use
value = value.replaceAll(“(?i)script”, “”); instead of
value = value.replaceAll(“(?i)script”, “”); for a case insensitive replacement.
Thanks,
-Tapas
about 11 months ago
Sorry , I meant ,
value = value.replaceAll(”(?i)script”, “”); instead of
value = value.replaceAll(”script”, “”); for a case insensitive replacement.
In my last comment…
about 1 month ago
Is there any updated code available for cleanXSS method, considering the comments provided above?