1. 程式人生 > >漏洞 host 攻擊 過濾器 新增白名單

漏洞 host 攻擊 過濾器 新增白名單

import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.Reader;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.springframework.util.ResourceUtils;

import com.itsv.gbp.core.web.filter.CustomException;

/**
 * @preserve
 */

public class IntceptorFilter extends HttpServlet implements Filter {
    private FilterConfig filterConfig; // Handle the passed-in FilterConfig

    public void init(FilterConfig filterConfig) throws ServletException {
        this.filterConfig = filterConfig;
    }

    /**
     * Process the request/response pair
     * 
     * @preserve
     */
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain filterChain) throws IOException {

        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse res = (HttpServletResponse) response;
        // hwj
        res.addHeader("Set-Cookie", " Path=/;  HttpOnly");  //Cookie 缺少 HttpOnly屬性
        res.addHeader("X-Frame-Options","SAMEORIGIN");  //防止 x-frame-options 缺失
        /*x-frame-options 屬性值
         * DENY 表示該頁面不允許在 frame 中展示,即便是在相同域名的頁面中巢狀也不允許。
         * SAMEORIGIN 表示該頁面可以在相同域名頁面的 frame 中展示
         * ALLOW-FROM uri表示該頁面可以在指定來源的 frame 中展示。
         */
        
        // 頭攻擊檢測host 新增白名單
        String requestHost = req.getHeader("host");  //當前訪問的url地址host
        if (requestHost != null && !isWhite(requestHost)) {
            res.setStatus(403);
            return;
        }

        
        // clientRequest 記錄真正的被請求的 URL 比如 /index.jsp;/login.jsp;/
        String home = req.getScheme() + "://" + req.getServerName() + ":"
                + req.getServerPort();

        String clientRequest = req.getRequestURL() + "?" + req.getQueryString();// req.getServletPath();
        System.out.println("過濾器===========" + clientRequest);

        // -------lfh 2016.2.24,針對登陸介面的引數判斷--------//
        Map parameters = request.getParameterMap();
        if (parameters != null && parameters.size() > 0) {
            for (Iterator iter = parameters.keySet().iterator(); iter.hasNext();) {
                String key = (String) iter.next();
                String[] values = (String[]) parameters.get(key);
                if ("dwdm".equals(key) || "password".equals(key)
                        || "dwdjzh".equals(key)) {
                    for (int i = 0; i < values.length; i++) {
                        if (!valueFilter1(values[i])
                                || !scriptingFilter(values[i])) {
                            try {
                                res.sendRedirect(home);
                            } catch (IOException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                            }
                            return;
                        }
                    }
                }
            }
        }
        // ---------------//

        // hwj
        String oldUrl = req.getRequestURL() + "";
        String newUrl = home;
        String[] urls = oldUrl.replaceAll(newUrl, "").split("/");// lfh20151116
        int urlslen = urls.length;// lfh20151116
        if(urlslen>0){
            oldUrl = urls[urlslen - 1].toLowerCase();// lfh20151116
        }
        
        // oldUrl=oldUrl.replaceAll(newUrl,
        // "").replaceAll("/","").toString().toLowerCase();//hwj
        oldUrl = oldUrl.substring(0, oldUrl.length());
        // if(oldUrl.equals("common") || oldUrl.equals("download") ||
        // oldUrl.equals("images") || oldUrl.equals("js") ||
        // oldUrl.equals("message") || oldUrl.equals("style")||
        // oldUrl.equals("system") || oldUrl.equals("upload") ||
        // oldUrl.equals("userfiles"))//hwj

        if (oldUrl.equals("system") || oldUrl.equals("userfiles"))// lfh20151116
        {
            try {
                res.sendRedirect(home);
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            return;
        }
        /*
         * if(sqlValidate(clientRequest)) { try { res.sendRedirect(home); }
         * catch (IOException e) { // TODO Auto-generated catch block
         * e.printStackTrace(); } return; }
         */

        // 如果使用者請求url或request引數中含有特殊字元 ,直接跳回首頁面 || !parametersFileter(req)
        if (!scriptingFilter(clientRequest)) {
            try {
                res.sendRedirect(home);
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            return;

        } else {

            req.setCharacterEncoding("GBK");
            doNext(request, response, filterChain);
            return;
        }

    }

    // 對所有屬性進行過濾
    private boolean parametersFileter(HttpServletRequest request) {
        Enumeration e = request.getParameterNames();
        String parameterName = "";
        String parameterValue = "";

        while (e.hasMoreElements()) {
            parameterName = (String) e.nextElement();
            parameterValue = request.getParameter(parameterName);
            System.out.println(parameterName + ": " + parameterValue + "");
            if (!valueFilter(parameterValue)) {
                return false;
            }
        }
        return true;
    }

    // 判斷屬性中是否含有特殊字元
    public boolean valueFilter(String paramValue) {
        String param = paramValue.toLowerCase(); // 轉換成小寫
        String paramLower = paramValue.toLowerCase();// 轉換成小寫
        if (paramValue != null && paramValue.length() > 0) {
            paramLower = paramLower.replaceAll("\\(", "").replaceAll("\\)", "")
                    .replaceAll("\'", "").replaceAll(" ", "")
                    .replaceAll("\"", "").replaceAll("<", "")
                    .replaceAll(">", "").replaceAll("\r", "")
                    .replaceAll("\n", "").replaceAll("!", "")
                    .replaceAll("=", "").replaceAll("iframe", "")
                    .replaceAll("alert", "")
                    .replaceAll("prompt", "").trim();
            // .replaceAll("update", "")
            // .replaceAll("delete", "")
            // .replaceAll("insert", "")
            // .replaceAll("select", "")
            // .replaceAll("(?i)and","")
            // .replaceAll("(?i)or","")
            // .replaceAll("(?i)not","")

        }
        return param.equals(paramLower);

    }

    public boolean valueFilter1(String paramValue) {
        String param = paramValue.toLowerCase(); // 轉換成小寫
        String paramLower = paramValue.toLowerCase();// 轉換成小寫
        if (paramValue != null && paramValue.length() > 0) {
            paramLower = paramLower.replaceAll("\\(", "").replaceAll("\\)", "")
                    .replaceAll("\'", "").replaceAll(" ", "")
                    .replaceAll("\"", "").replaceAll("<", "")
                    .replaceAll(">", "").replaceAll("\r", "")
                    .replaceAll("\n", "").replaceAll("!", "")
                    .replaceAll("=", "").replaceAll("iframe", "")
                    .replaceAll("script", "").replaceAll("alert", "")
                    .replaceAll("prompt", "").replaceAll("confirm", "")
                    .replaceAll("update", "").replaceAll("delete", "")
                    .replaceAll("insert", "").replaceAll("select", "")
                    .replaceAll("(?i)and", "").replaceAll("(?i)or", "")
                    .replaceAll("(?i)not", "").trim();

        }
        return param.equals(paramLower);

    }

    private void doNext(ServletRequest request, ServletResponse response,
            FilterChain filterChain) {
        try {
            filterChain.doFilter(request, response);
        } catch (ServletException sx) {
            filterConfig.getServletContext().log(sx.getMessage());
            
            String message = "";
            Exception e=(Exception) sx.getRootCause();
            if(e instanceof CustomException){
                message = "{\"errorCode\":\"999\",\"message\":\""+e.getMessage()+"\"}";
            } else if(e instanceof NoSuchMethodException){
                String className = sx.getMessage();
                if(className.indexOf("com.itsv.chy.wsqh.zdwh.action.WebServiceAction")!=-1){
                    message="{\"errorCode\":\"998\",\"message\":\"該介面方法不存在\"}";
                }
            }
            if(!StringUtils.isEmpty(message)){
                PrintWriter out = null;
                try {
                    response.setContentType("application/json;charset=UTF-8");
                    out = response.getWriter();
                    out.print(message);
                    out.flush();
                } catch (IOException e1) {
                    e1.printStackTrace();
                } finally {
                    if (out != null) {
                        out.close();
                    }
                }
            }
        } catch (IOException iox) {
            filterConfig.getServletContext().log(iox.getMessage());
        } 
    }

    /*
     * // 對url字串進行過濾 public String scriptingFilter(String value) {
     * 
     * if(value ==null){ return null; }
     * 
     * StringBuffer result = new StringBuffer(value.length());
     * 
     * for(int i=0; i<value.length(); ++i){ switch(value.charAt(i)){ case '<' :
     * result.append("&lt;"); break; case '>' : result.append("&gt;"); break;
     * case '"' : result.append("&quot;"); break; case '\'':
     * result.append("&#39;"); break; case '%' : result.append("&#37;"); break;
     * // case ';' : result.append("&#59;"); break; case '(' :
     * result.append("&#40;"); break; case ')' : result.append("&#41;"); break;
     * // case '&' : result.append("&amp;"); break; case '+' :
     * result.append("&#43;"); break; default : result.append(value.charAt(i));
     * break; }
     * 
     * }
     * 
     * return new String(result); }
     */
    // 判斷屬性中是否含有特殊字元
    public boolean scriptingFilter(String paramValue) {
        String param = paramValue.toLowerCase(); // 轉換成小寫
        String paramLower = paramValue.toLowerCase();// 轉換成小寫
        if (paramValue != null && paramValue.length() > 0) {
            paramLower = paramLower.replaceAll("\'", "").replaceAll(" ", "")
                    .replaceAll("\"", "").replaceAll("<", "")
                    .replaceAll(">", "").replaceAll("\r", "")
                    .replaceAll("\n", "").replaceAll("!", "")
                    // hwj
                    /*
                     * .replaceAll("\\(", "") .replaceAll("\\)", "")
                     * .replaceAll("%7d", "")//} .replaceAll("%7b", "")//{
                     * .replaceAll("\\[", "") .replaceAll("\\]", "")
                     */
                    .replaceAll("iframe", "")
                    //.replaceAll("script", "")
                    .replaceAll("alert", "").replaceAll("confirm", "")
                    // hwj
                    /*
                     * .replaceAll("document", "") .replaceAll("eval", "")
                     */
                    .replaceAll("prompt", "").trim();

        }
        return param.equals(paramLower);

    }

    // hwj
    /*
     * //效驗 protected static boolean sqlValidate(String str) { str =
     * str.toLowerCase();//統一轉為小寫 String badStr =
     * "'|and|exec|execute|insert|select|delete|update|count|drop|*|%|chr|mid|master|truncate|"
     * +
     * "char|declare|sitename|net user|xp_cmdshell|;|or|+|,|like'|and|exec|execute|insert|create|drop|"
     * + "table|from|grant|group_concat|column_name|" +
     * "information_schema.columns|table_schema|union|where|select|delete|update|order|by|count|*|"
     * +
     * "chr|mid|master|truncate|char|declare|or|;|-|--|+|,|like|#";//過濾掉的sql關鍵字
     * ,可以手動新增 String[] badStrs = badStr.split("\\|"); for (int i = 0; i <
     * badStrs.length; i++) { if (str.indexOf(badStrs[i]) >= 0) { return true; }
     * } return false; }
     */
    public static String StringFilter(String str) throws PatternSyntaxException {

        // 清除掉所有特殊字元
        String regEx = "[`[email protected]#$%^&*()+=|{}':;',\\[\\].<>/?~!@#¥%……&*()——+|{}【】‘;:”“’。,、?《》]";
        Pattern p = Pattern.compile(regEx);
        Matcher m = p.matcher(str);
        return m.replaceAll("").trim();

    }
    /**
     * 判斷host 是否存在白名單內
     * serverWhiteList.json 檔案內配置白名單 用;隔開
     * @param host
     * @return
     */
     public static boolean isWhite(String host) {
         String jsonstr = readJsonFile("serverWhiteList.json");  
         if(jsonstr ==null || jsonstr.length()==0){
             return true;
         }
         String[] jsonstrs = jsonstr.split(";");
         
         for(String str : jsonstrs){
             if (str != null && str.equals(host)) {
                    return true;
              }
         }
         return false;
        }
     /**
      * 獲取json 檔案內容
      * @param fileName  json 檔名稱
      * @return
      */
     public static  String readJsonFile(String fileName) {
         String jsonStr = "";
         try {
             File jsonFile = ResourceUtils.getFile("classpath:"+fileName);   //獲取根目錄下的json 檔案
             FileReader fileReader = new FileReader(jsonFile);
             Reader reader = new InputStreamReader(new FileInputStream(jsonFile),"utf-8");
             int ch = 0;
             StringBuffer sb = new StringBuffer();
             while ((ch = reader.read()) != -1) {
                 sb.append((char) ch);
             }
             fileReader.close();
             reader.close();
             jsonStr = sb.toString();
             return jsonStr;
        } catch (Exception e) {
            return jsonStr;
            // TODO: handle exception
        }
     }
    /**
     * Clean up resources
     * 
     * @preserve
     */
    public void destroy() {

    }
}
 

 

json 檔案內格式 localhost:7001;localhost:7002;