xss攻击防御springMVC表单提交数据过滤/转义

Markdown及扩展

背景1:spring中的filter拦截request中请求入参,但对于post提交的表单无效
背景2:测试工具firefox的hackbar,postData:idNum=idNum=14043’%3bconfirm(1)%2f%2f846&seNo=&clientName=

代码块

前端代码:

"${path}/test" id="selectForm" method="post"> "hidden" id="idNum" name="idNum" value="${idNum}"/> "hidden" id="seNo" name="seNo" value="${seNo}"/> "hidden" id="clientName" name="clientName" value="${clientName}"/>

后端代码:

    @RequestMapping(value = "/test",method = RequestMethod.POST)
    @ResponseBody
    public ModelAndView fill(@RequestParam(value = "idNum", required = false) String idNum,
            @RequestParam(value = "seNo", required = false) String seNo,
            @RequestParam(value = "clientName", required = false) String clientName) {
        ModelAndView view = new ModelAndView("/claims/claimsfill");
        view.addObject("idNum",idNum);
        view.addObject("seNo",seNo);
        view.addObject("clientName",clientName);
        return view;
    }

过滤器:

import java.io.IOException;
import java.util.Enumeration;
import java.util.Map;
import java.util.Vector;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;

public class XSSFilter extends OncePerRequestFilter {
    public void setExclude(String exclude) {
        this.exclude = exclude;
        pattern = Pattern.compile(getRegStr(exclude));
    }
    /**
     * XSS过滤
     */
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {
        String requestURI = request.getRequestURI();
        if(StringUtils.isNotBlank(requestURI))
            requestURI = requestURI.replace(request.getContextPath(),"");
            EscapeScriptwrapper escapeScriptwrapper = new EscapeScriptwrapper(request);
            filterChain.doFilter(escapeScriptwrapper, response);
    }

    /**
     * 将传递进来的不需要过滤得路径集合的字符串格式化成一系列的正则规则
     * @param str 不需要过滤的路径集合
     * @return 正则表达式规则
     * */
    private String getRegStr(String str){
        if(StringUtils.isNotBlank(str)){
            String[] excludes = str.split(";");  //以分号进行分割
            int length = excludes.length;
            for(int i=0;i{
                String tmpExclude = excludes[i];
                //对点、反斜杠和星号进行转义
                tmpExclude = tmpExclude.replace("\\", "\\\\").replace(".", "\\.").replace("*", ".*");

                tmpExclude = "^" + tmpExclude + "$";
                excludes[i] = tmpExclude;
            }
            return StringUtils.join(excludes, "|");
        }
        return str;
    }

    /**
     * 继承HttpServletRequestWrapper,创建装饰类,以达到修改HttpServletRequest参数的目的
     * */
    private class EscapeScriptwrapper extends HttpServletRequestWrapper{
        private Map<String, String[]> parameterMap;  //所有参数的Map集合
        public EscapeScriptwrapper(HttpServletRequest request) {
            super(request);
            parameterMap = request.getParameterMap();
        }

        //重写几个HttpServletRequestWrapper中的方法
        /**
         * 获取所有参数名
         * @return 返回所有参数名
         * */
        @Override
        public Enumeration<String> getParameterNames() {
            Vector<String> vector = new Vector<String>(parameterMap.keySet());
            return vector.elements();
        }

        /**
         * 获取指定参数名的值,如果有重复的参数名,则返回第一个的值
         * 接收一般变量 ,如text类型
         * 
         * @param name 指定参数名
         * @return 指定参数名的值
         * */
        @Override
        public String getParameter(String name) {
            String[] results = parameterMap.get(name);
            if(results == null || results.length <= 0)
                return null;
            else{
                return escapeXSS(results[0]);
            }
        }

        /**
         * 获取指定参数名的所有值的数组,如:checkbox的所有数据
         * 接收数组变量 ,如checkobx类型
         * */
        @Override
        public String[] getParameterValues(String name) {
            String[] results = parameterMap.get(name);
            if(results == null || results.length <= 0)
                return null;
            else{
                int length = results.length;
                for(int i=0;i{
                    results[i] = escapeXSS(results[i]);
                }
                return results;
            }
        }

        /**
         * 过滤字符串中的js脚本
         * 解码:StringEscapeUtils.unescapeXml(escapedStr)
         * */
        private String escapeXSS(String str){
            str = StringEscapeUtils.escapeXml(str);

            Pattern tmpPattern = Pattern.compile("[sS][cC][rR][iI][pP][tT]");
            Matcher tmpMatcher = tmpPattern.matcher(str);
            if(tmpMatcher.find()){
                str = tmpMatcher.replaceAll(tmpMatcher.group(0) + "\\\\");
            }
            return str;
        }
    }

}

web.xml:


    xssFilter
    class>com.ahut.ngsp.insite.filter.XSSFilterfilter-class>
filter>
<filter-mapping>
    <filter-name>xssFilterfilter-name>
    <url-pattern>/*url-pattern>
filter-mapping>

你可能感兴趣的:(安全)