whycxzp
2023-07-05 c7bc2cdbb75292d9d4d12cf02884f8f140f22009
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
package com.whyc.filter;
 
import com.whyc.constant.YamlProperties;
import org.apache.commons.lang.StringUtils;
import org.springframework.web.bind.annotation.RequestMethod;
 
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.Enumeration;
 
/**
 * 防止LDAP盲注
 */
@WebFilter
public class LDAPFilter implements Filter {
 
    private static final char[] LDAP_FORBIDDEN_REQUEST = new char[]{'\\', '*', '(', ')', '\0', '/','&','!','|'};
    private static final char[] LDAP_FORBIDDEN_BODY = new char[]{'\\', '*', '(', ')', '\0', '/','&','!','|'};
    //private static final String[] LDAP_FILTER_ESCAPE_SEQUENCE_CHARACTER = new String[]{"\\5c", "\\2a", "\\28", "\\29", "\\00", "\\2f"};
 
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
 
    }
 
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        //严格要求
        if(2 == YamlProperties.systemType) {
            String requestURI = request.getRequestURI();
 
            //url上的参数进行过滤
            Enumeration<String> parameterNames = request.getParameterNames();
            while (parameterNames.hasMoreElements()) {
                String paramName = parameterNames.nextElement();
                String paramValue = request.getParameter(paramName);
                if (StringUtils.isBlank(paramValue)) {
                    continue;
                }
                for (char c : LDAP_FORBIDDEN_REQUEST) {
                    int index = paramValue.indexOf(c);
                    if (index != -1) {
                        //paramValue = paramValue.replace(String.valueOf(LDAP_FILTER_ESCAPE_SEQUENCE[charIndex]), LDAP_FILTER_ESCAPE_SEQUENCE_CHARACTER[charIndex]);
                        //这个里面是允许*的,可以放过
                        if (
                                (requestURI.contains("user/") && c == '*' && (request.getMethod().toUpperCase().equals(RequestMethod.POST.name()) || request.getMethod().toUpperCase().equals(RequestMethod.PUT.name())))
                        ) {
                            continue;
                        } else if ((requestURI.contains(".servlet") || requestURI.contains("menu/menuList")) && c == '/') {
                            continue;
                        }
                        response.setStatus(403);
                        response.getWriter().write("非法请求,不允许包含特殊字符");
                        return;
                    }
                }
            }
            //body的参数进行过滤
            StringBuilder requestBody = new StringBuilder();
            String temp = "";
            //BufferedReader reader = new BufferedReader(new InputStreamReader(request.getInputStream()));
            ServletRequest requestWrapper = new BodyReaderHttpServletRequestWrapper(request);
            BufferedReader reader = requestWrapper.getReader();
            while ((temp = reader.readLine()) != null) {
                requestBody.append(temp);
            }
            reader.close();
 
            for (char c : LDAP_FORBIDDEN_BODY) {
                int index = requestBody.toString().indexOf(c);
                if (index != -1) {
                    //这个里面是允许*的,可以放过
                    if (
                            (requestURI.contains("user/") && c == '*' && (request.getMethod().toUpperCase().equals(RequestMethod.POST.name()) || request.getMethod().toUpperCase().equals(RequestMethod.PUT.name())))
 
                    ) {
                        continue;
                    } else if ((requestURI.contains(".servlet") || requestURI.contains("menu/menuList")) && c == '/') {
                        continue;
                    }
 
                    //paramValue = paramValue.replace(String.valueOf(LDAP_FILTER_ESCAPE_SEQUENCE[charIndex]), LDAP_FILTER_ESCAPE_SEQUENCE_CHARACTER[charIndex]);
                    response.setStatus(403);
                    response.getWriter().write("非法请求,不允许包含特殊字符");
                    return;
                }
            }
            filterChain.doFilter(requestWrapper,servletResponse);
        }else{
            filterChain.doFilter(request,response);
        }
 
    }
 
    @Override
    public void destroy() {
 
    }
}