首先创建一个类继承ServletRequestWrapper类,重写request请求
import java.io.StringReader;
import java.io.StringWriter;
import java.text.CharacterIterator;
import java.text.StringCharacterIterator;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import com.blogspot.radialmind.html.HTMLParser;
import com.blogspot.radialmind.xss.XSSFilter;
public class ServletRequestWrapper extends HttpServletRequestWrapper {
HttpServletRequest orgRequest = null;
private static String[] keywords ={"|","&",";","$","%","@","'","\'","\"","/>","<>","()","+","cr","lf","\\","ASCII",
"../","./","*","=","char","sysopen","execute","exec","net user","/add"
,"create","modify","union","join","select","insert", "update", "delete", "drop", "truncate"};
public servletRequestWrapper(HttpServletRequest request) {
super(request);
orgRequest = request;
}
/**
* 覆盖getParameter方法,将参数名和参数值都做xss过滤。
* 如果需要获得原始的值,则通过super.getParameterValues(name)来获取
* getParameterNames,getParameterValues和getParameterMap也可能需要覆盖
*/
@Override
public String getParameter(String name) {
String value = super.getParameter(xssEncode(name));
if (value != null) {
value = xssEncode(value);
value = HTMLEncode(value);
value=isSafe(value);//过滤sql注入字符
}
}
return value;
}
/**
* 过滤特殊字符
* @param str
* @return
*/
private static String isSafe(String str) {
if (null != str && str.length() > 0) {
for (String s : keywords) {
if (str.toLowerCase().contains(s)) {
str=str.replaceAll(s,"");
}
}
}
return str;
}
/**
* 对一些特殊字符进行转义
*
*
*/
public static String HTMLEncode(String aText){
final StringBuilder result = new StringBuilder();
final StringCharacterIterator iterator = new StringCharacterIterator(aText);
char character = iterator.current();
while (character != CharacterIterator.DONE ){
if (character == '<') {
result.append("<");
}else if (character == '>') {
result.append(">");
}else if (character == '&') {
result.append("&");
}else if (character == '\"') {
result.append(""");
}else {
//the char is not a special one
//add it to the result as is
result.append(character);
}
character = iterator.next();
}
return result.toString();
}
/**
* 覆盖getHeader方法,将参数名和参数值都做xss过滤。 如果需要获得原始的值,则通过super.getHeaders(name)来获取
* getHeaderNames 也可能需要覆盖
*/
@Override
public String getHeader(String name) {
String value = super.getHeader(xssEncode(name));
if (value != null) {
value = xssEncode(value);
}
return value;
}
/**
* 将容易引起xss漏洞的半角字符直接替换成全角字符
*
* @param s
* @return
*/
private static String xssEncode(String s) {
if (s == null || s.isEmpty()) {
return s;
}
StringReader reader = new StringReader(s);
StringWriter writer = new StringWriter();
try {
HTMLParser.process(reader, writer, new XSSFilter(), true);
String result = writer.toString();
/*System.out.println("xssEncode-------------------------" + s + " = "
+ result);*/
return result;
} catch (NullPointerException e) {
return s;
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
/**
* 获取最原始的request
*
* @return
*/
public HttpServletRequest getOrgRequest() {
return orgRequest;
}
/**
* 获取最原始的request的静态方法
*
* @return
*/
public static HttpServletRequest getOrgRequest(HttpServletRequest req) {
if (req instanceof XssHttpServletRequestWrapperNew) {
return ((XssHttpServletRequestWrapperNew) req).getOrgRequest();
}
return req;
}
}
然后创建一个过滤器,过滤相关内容
import java.io.IOException;
import java.util.Enumeration;
import java.util.regex.Pattern;
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;
import javax.servlet.http.HttpServletResponse;
/**
* <code>{@link CharLimitFilter}</code>
*
* 拦截防止sql注入和XSS攻击
*
* @author zc
*/
public class XssFilter implements Filter {
FilterConfig filterConfig = null;
private static String[] excludePaths={""};// 不进行拦截的url,逗号隔开
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 {
HttpServletRequest httprequest = (HttpServletRequest) request;
HttpServletResponse httpresponse = (HttpServletResponse) response;
String requestUrl = httprequest.getRequestURI();//请求url
if (excludeUrl(requestUrl)) {//放开不需要过滤的请求地址
chain.doFilter(request, response);
}else{
chain.doFilter(new XssHttpServletRequestWrapperNew((HttpServletRequest) request), response);
}
}
private boolean excludeUrl(String url) {
if (excludePaths != null && excludePaths.length > 0) {
for (String path : excludePaths) {
if (url.contains(path)) {
return true;
}
}
}
return false;
}
}
最后在web.xml里配置拦截器
<!-- 特殊字符过滤start -->
<filter>
<filter-name>XssSqlFilter</filter-name>
<filter-class>com.wondersgroup.falcon.filter.XssFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>XssSqlFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 特殊字符过滤end -->
本文介绍了如何通过继承HttpServletRequestWrapper来重写request请求,以防御SQL注入和XSS攻击。首先,创建一个继承ServletRequestWrapper的类,接着实现过滤敏感内容的逻辑。然后,设置一个过滤器来应用这个自定义请求包装器。最后,在web.xml配置文件中配置该过滤器以拦截并处理所有请求。

1674

被折叠的 条评论
为什么被折叠?



