JFinal

登录 注册

xss过滤

打算在 jfinal中实现xss过滤,参考了 http://www.jfinal.com/feedback/571 决定采用handler统一处理,又找到 http://blog.dreamlu.net/blog/57 发现有些问题,经修改后测试可用

package demo.handler;

import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.jsoup.Jsoup;
import org.jsoup.safety.Whitelist;

/**
* 重写HttpServletRequestWrapper用于配合XssHandler
* @author oycw
* @date 创建时间:2017年5月18日 下午1:49:26
*/
public class XssHttpServletRequestWrapper extends javax.servlet.http.HttpServletRequestWrapper{
 
    public XssHttpServletRequestWrapper(HttpServletRequest request) {
        super(request);
    }
 
    /**
     * 重写并过滤getParameter方法
     */
    @Override
    public String getParameter(String name) {
        return 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] = getBasicHtmlandimage(values[i]);
        }
        return values;
    }
     
    /**
     * 重写并过滤getParameterMap方法
     */
    @Override
    public Map<String,String[]> getParameterMap() {
		@SuppressWarnings("unchecked")
		Map<String,String[]> paraMap = super.getParameterMap();
        // 对于paraMap为空的直接return
        if (null == paraMap || paraMap.isEmpty()) {
            return paraMap;
        }
        
        //super.getParameterMap()不允许任何修改,所以只能做深拷贝
        Map<String, String[]> paraMapCopy = new HashMap<String, String[]>();
        //实际上putAll只对基本类型深拷贝有效,如果是自定义类型,则要找其他办法
        paraMapCopy.putAll(paraMap);
        
        for (Map.Entry<String, String[]> entry : paraMapCopy.entrySet()) {
            String[] values     = entry.getValue();
            if (null == values) {
                continue;
            }
            String[] newValues  = new String[values.length];
            for (int i = 0; i < values.length; i++) {
                newValues[i] = getBasicHtmlandimage(values[i]);
            }
            entry.setValue(newValues);
        }
        return paraMapCopy;
    }
    
    private static String getBasicHtmlandimage(String html) {
	    if (html == null)
	        return null;
	    return Jsoup.clean(html, Whitelist.basicWithImages());
	}
}
package demo.handler;
import java.util.regex.Pattern;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.jsoup.helper.StringUtil;

import com.jfinal.handler.Handler;

/**
* 全局xss过滤
* @author oycw
* @date 创建时间:2017年5月18日 下午1:45:37
*/
public class XssHandler extends Handler {

	 // 排除的url,使用的target.startsWith匹配的
    private String excludePattern;
     
    /**
     * 忽略列表,使用正则
     * @param exclude
     */
    public XssHandler(String excludePattern) {
        this.excludePattern = excludePattern;
    }

	@Override
	public void handle(String target, HttpServletRequest request, HttpServletResponse response, boolean[] isHandled) {

		java.util.regex.Pattern pattern = Pattern.compile(excludePattern);
		//带.表示非action请求,忽略(其实不太严谨,如果是伪静态,比如.html会被错误地排除);匹配excludePattern的,忽略
        if (target.indexOf(".") == -1 && !(!StringUtil.isBlank(excludePattern) && pattern.matcher(target).find() ) ){
            request = new XssHttpServletRequestWrapper(request);
        }
        //别忘了
        next.handle(target, request, response, isHandled);
        
	}

	 

}


评论