前天公司的网站在《360安全检测》上发现了大量xss漏洞。好吧,我立马懂了,除了我做得有几个模块过滤了之外,别的几乎100%存在!
对于这个东西怎么解决呢?狠是纠结了一番,一个个去改controller吗?好吧这不是我的风格,我没这么勤快!使用拦截器么?(公司使用的是Spring MVC)貌似也解决不了问题?最后使用Filter将问题统一处理OK,其原理是重写掉Request中的getParameter、getParameterValues和getParameterMap方法,使用jsoup清理掉消除不受信任的HTML!
废话不多说,贴代码!下面是我在JFinal中使用handler的实现!
//XssHandler.java
/**
* 统一XSS处理
* @author L.cm
* email: 596392912@qq.com
* site: http://www.dreamlu.net
* @date 2014-5-5 上午9:11:10
*/
public class XssHandler extends Handler {
// 排除的url,使用的target.startsWith匹配的
private String exclude;
public XssHandler(String exclude) {
this.exclude = exclude;
}
@Override
public void handle(String target, HttpServletRequest request,
HttpServletResponse response, boolean[] isHandled) {
// 对于非静态文件,和非指定排除的url实现过滤
if (target.indexOf(".") == -1 && !target.startsWith(exclude)){
request = new HttpServletRequestWrapper(request);
}
nextHandler.handle(target, request, response, isHandled);
}
}
在jfinal中我添加了一个exclude参数来排除后台Admin中的参数的清理工作!
//HttpServletRequestWrapper.java
/**
* 对HttpServletRequestWrapper重写,为了统一XSS处理加上懒写成这样了
* @author L.cm
* email: 596392912@qq.com
* site: http://www.dreamlu.net
* @date 2014-5-5 上午9:10:18
*/
public class HttpServletRequestWrapper extends javax.servlet.http.HttpServletRequestWrapper{
public HttpServletRequestWrapper(HttpServletRequest request) {
super(request);
}
/**
* 重写并过滤getParameter方法
*/
@Override
public String getParameter(String name) {
return HtmlFilter.getBasicHtmlandimage(super.getParameter(name));
}
/**
* 重写并过滤getParameterValues方法
*/
@Override
public String[] getParameterValues(String name) {
String[] values = super.getParameterValues(name);
if (null == values){
return null;
}
for (int i = 0; i < values.length; i++) {
values[i] = HtmlFilter.getBasicHtmlandimage(values[i]);
}
return values;
}
/**
* 重写并过滤getParameterMap方法
*/
@Override
public Map getParameterMap() {
Map paraMap = super.getParameterMap();
// 对于paraMap为空的直接return
if (null == paraMap || paraMap.isEmpty()) {
return paraMap;
}
for (Entry entry : paraMap.entrySet()) {
String key = entry.getKey();
String[] values = entry.getValue();
if (null == values) {
continue;
}
String[] newValues = new String[values.length];
for (int i = 0; i < values.length; i++) {
newValues[i] = HtmlFilter.getBasicHtmlandimage(values[i]);
}
paraMap.put(key, newValues);
}
return paraMap;
}
}
Jsoup中会对HTML的attr同样过滤,因为部分attr也是不安全的!
// HtmlFilter.java
//在basic基础上 增加图片通过
public static String getBasicHtmlandimage(String html) {
if (html == null)
return null;
return Jsoup.clean(html, Whitelist.basicWithImages());
}
OK,到此大功告成!