xss attack defense springMVC form submission data filtering/escaping

Markdown and extensions

Background 1: The filter in spring intercepts the request input parameters, but it is invalid for the form submitted by post.
Background 2: The hackbar of the test tool firefox, postData:idNum=idNum=14043'%3bconfirm(1)%2f%2f846&seNo=&clientName=

code block

Front-end code:

<form action="${path}/test" id="selectForm" method="post">
         <input type="hidden" id="idNum" name="idNum" value="${idNum}"/>
         <input type="hidden" id="seNo" name="seNo" value="${seNo}"/>
         <input type="hidden" id="clientName" name="clientName" value="${clientName}"/>
</form>

Backend code:

    @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;
    }

filter:

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<length;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<length;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 :

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

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324789982&siteId=291194637