开发者社区> 问答> 正文

java Filter 并发问题? 400 报错

java Filter 并发问题? 400 报错

filter代码如下

package com.zdmoney.laocaibao.common.filter;/**
 * Created by pc05 on 2017/6/5.
 */

import com.zdmoney.laocaibao.common.client.ClientEnum;
import com.zdmoney.laocaibao.common.utils.CommonUtils;
import com.zdmoney.laocaibao.common.utils.HtmlFilterUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
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;

/**
 * 描述 : xss攻击过滤器
 *
 * @author : huangcy
 * @create : 2017-06-05 10:04
 * @email : huangcy01@zendaimoney.com
 **/
public class XssFilter extends OncePerRequestFilter {
    private String exclude = null;  //不需要过滤的路径集合
    private Pattern pattern = null;  //匹配不需要过滤路径的正则表达式

    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 {
        System.out.println("********************"+request.getAttribute(getAlreadyFilteredAttributeName())+"&&"+request+"&&"+request.getParameterMap()+"&&"+request.isSecure()+request.isAsyncStarted()+request.isAsyncSupported()+request.isRequestedSessionIdValid());
        StringBuffer requestURL = request.getRequestURL();
        if(StringUtils.contains(requestURL,"/credit")){
            request.getSession().setAttribute("clientPath", CommonUtils.getClientPath(ClientEnum.BORROWER));
        }else {
            request.getSession().setAttribute("clientPath", CommonUtils.getClientPath(ClientEnum.FINANCIAL));
        }
        String requestURI = request.getRequestURI();
        if(StringUtils.isNotBlank(requestURI))
            requestURI = requestURI.replace(request.getContextPath(),"");

        if(pattern.matcher(requestURI).matches())
            filterChain.doFilter(request, response);
        else{
            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参数的目的
     * */
    public class EscapeScriptwrapper extends HttpServletRequestWrapper {
        private Map<String, String[]> parameterMap;  //所有参数的Map集合
        public EscapeScriptwrapper(HttpServletRequest request) {
            super(request);
            parameterMap = request.getParameterMap();
        }

        /**
         * 获取所有参数名
         * @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 = HtmlFilterUtils.htmlEncode(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.zdmoney.laocaibao.common.filter.XssFilter</filter-class>
        <init-param>
            <param-name>exclude</param-name>
            <param-value>/static/*</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>xssFilter</filter-name>
        <url-pattern>/*</url-pattern>
        <!-- 直接从客户端过来的请求以及通过forward过来的请求都要经过该过滤器 -->
        <dispatcher>REQUEST</dispatcher>
        <dispatcher>FORWARD</dispatcher>
    </filter-mapping>

多个请求有的能获取到数据有的获取不到数据

展开
收起
爱吃鱼的程序员 2020-06-03 15:06:20 838 0
1 条回答
写回答
取消 提交回答
  • https://developer.aliyun.com/profile/5yerqm5bn5yqg?spm=a2c6h.12873639.0.0.6eae304abcjaIB

    Filter没有并发的问题

    ######回复 @风吹屁屁凉 : 嗯嗯 可能描述不准确 但是是在找不到问题所在呀######

    完全看不到报错,还有过滤的太简单了。。。可以看下XSS跨站那本红书,里面前几页有个绕过Filter的

    2020-06-03 17:20:51
    赞同 展开评论 打赏
问答分类:
问答地址:
问答排行榜
最热
最新

相关电子书

更多
Spring Cloud Alibaba - 重新定义 Java Cloud-Native 立即下载
The Reactive Cloud Native Arch 立即下载
JAVA开发手册1.5.0 立即下载