需要编写一个xssFilter过滤器,对request对象进行包装后提供给程序使用。
XssFilter过滤器源码
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
/**
* <code>{@link CharLimitFilter}</code>
*
* 拦截防止sql注入
*
* @author Administrator
*/
public class XssFilter implements Filter {
private static final String INIT_PARAM_EXCUDEURLS="excludeUrls";
/**
* 不过滤的url
*/
protected String excludeUrls;
private boolean excluded=false;
/*
* (non-Javadoc)
*
* @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest,
* javax.servlet.ServletResponse, javax.servlet.FilterChain)
*/
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest servletRequest=(HttpServletRequest) request;
String url=servletRequest.getRequestURI();
if (url.indexOf("?")>-1)
url=url.substring(0, url.indexOf("?"));
for (String tempUrl:excludeUrls.split(",")){
if (url.indexOf(tempUrl)>-1){
excluded=true;
break;
}
}
if (!excluded){
XssHttpServletRequestWrapper xssRequest = new XssHttpServletRequestWrapper(
(HttpServletRequest) request);
filterChain.doFilter(xssRequest, response);
}
else
filterChain.doFilter(servletRequest, response);
}
@Override
public void destroy() {
// TODO Auto-generated method stub
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
excludeUrls=filterConfig.getInitParameter(INIT_PARAM_EXCUDEURLS);
}
}
XssHttpServletRequestWrapper request包装器源码
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
/**
* <code>{@link XssHttpServletRequestWrapper}</code>
*
* TODO : document me
*
* @author Administrator
*/
public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {
HttpServletRequest orgRequest = null;
public XssHttpServletRequestWrapper(HttpServletRequest request) {
super(request);
orgRequest = request;
}
/**
* 覆盖getParameter方法,将参数名和参数值都做xss过滤。<br/>
* 如果需要获得原始的值,则通过super.getParameterValues(name)来获取<br/>
* getParameterNames,getParameterValues和getParameterMap也可能需要覆盖
*/
@Override
public String getParameter(String name) {
String value = super.getParameter(xssEncode(name));
if (value != null) {
value = xssEncode(value);
}
return value;
}
/**
* 覆盖getHeader方法,将参数名和参数值都做xss过滤。<br/>
* 如果需要获得原始的值,则通过super.getHeaders(name)来获取<br/>
* getHeaderNames 也可能需要覆盖
*/
@Override
public String getHeader(String name) {
String value = super.getHeader(xssEncode(name));
if (value != null) {
value = xssEncode(value);
}
return value;
}
/**
* 使用struts2必须重写该方法
*
* @return
*/
@Override
public Map<String, String[]> getParameterMap() {
Map<String, String[]> parameterMap = super.getParameterMap();
Set<Map.Entry<String, String[]>> entrySet = parameterMap.entrySet();
for (Map.Entry<String, String[]> entry : entrySet) {
if (Validator.isNotNull(entry.getValue()) && entry.getValue().length > 0) {
String[] encodeVals = new String[entry.getValue().length];
int i = 0;
for (String value : entry.getValue()) {
String encodeVal = xssEncode(value);
encodeVals[i++] = encodeVal;
}
entry.setValue(encodeVals);
}
}
return parameterMap;
}
@Override
public String[] getParameterValues(String name) {
String[] values = super.getParameterValues(name);
String[] escapeValues = new String[values.length];
for (int i=0; i<values.length; i++) {
escapeValues[i] = xssEncode(values[i]);
}
return escapeValues;
}
/**
* 将容易引起xss漏洞的半角字符直接替换成全角字符
*
* @param s
* @return
*/
private static String xssEncode(String s) {
if (s == null || "".equals(s)) {
return s;
}
StringBuilder sb = new StringBuilder(s.length() + 16);
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
switch (c) {
case '>':
sb.append(">");// 全角大于号
break;
case '<':
sb.append("<");// 全角小于号
break;
case '\'':
sb.append("'");// 全角单引号
break;
case '\"':
sb.append(""");// 全角双引号
break;
default:
sb.append(c);
break;
}
}
return sb.toString();
}
/**
* 获取最原始的request
*
* @return
*/
public HttpServletRequest getOrgRequest() {
return orgRequest;
}
/**
* 获取最原始的request的静态方法
*
* @return
*/
public static HttpServletRequest getOrgRequest(HttpServletRequest req) {
if (req instanceof XssHttpServletRequestWrapper) {
return ((XssHttpServletRequestWrapper) req).getOrgRequest();
}
return req;
}
}
特殊字符替代方式
显示结果 | 描述 实体名称 | 实体编号 |
---|---|---|
空格 | ||
< 小于号 | & lt; | & #60; |
> 大于号 | & gt; | & #62; |
& 和号 | & amp; | & #38; |
” 引号 | & quot; | & #34; |
’ 撇号 | & apos; (IE不支持) | & #39; |
(由于编辑器限制,上述对应的转换字符&号后面都有加空格,正式使用时要去掉。)