天天看點

Java Web項目漏洞:檢測到目标URL存在http host頭攻擊漏洞解決辦法

背景

項目上線之後使用綠盟或Acunetix安全掃描工具掃描後發現了頭攻擊漏洞。截圖如下:

漏洞提示

檢測工具在檢測出漏洞後給予的提示為:

大意為不要使用request中的serverName,也就是說host header可能會在攻擊時被篡改,依賴request的方法是不可靠的,形如JSP頭部中的:

String path = request.getContextPath();

String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";

1

2

這樣的使用方法就會被漏洞檢測工具查出來,認定有頭攻擊漏洞。

解決辦法

提示中說,如果是php的話不要用_SERVER[“HTTP_HOST”],apache和Nginx通過設定虛拟機來紀要非法header,而web開發中常見的運作容器就是tomcat,網絡查找出的解決方案大多不适用,最後,我們找到了一個折中的辦法。

主要解決辦法,就是在請求攔截上面做host合法性校驗,攔截掉非法請求。

public class SessionFilter implements Filter {

    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException,

            ServletException {

        HttpServletRequest request = (HttpServletRequest) req;

        HttpServletResponse response = (HttpServletResponse) res;

        // 頭攻擊檢測

        String requestHost = request.getHeader("host");

        if (requestHost != null && !ServerWhiteListUtil.isWhite(requestHost)) {

            response.setStatus(403);

            return;

        }

        ...

    }

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

上述代碼是常見的web系統攔截器doFilter方法,我們在方法開始的地方做host判定,如果不在白名單内,則傳回403狀态碼。漏洞工具收到403後認為通路請求已被終止,就不會報錯了。

其中,ServerWhiteListUtil.isWhite(requestHost))方法:

package ...;

import java.io.InputStreamReader;

import java.util.List;

import com.google.gson.Gson;

import com.google.gson.reflect.TypeToken;

/**

 * 伺服器白名單清單

 */

public class ServerWhiteListUtil {

    private static List<String> whiteList = null;;

    static {

        try {

            // 讀取白名單清單

            whiteList = new Gson().fromJson(

                    new InputStreamReader(ServerWhiteListUtil.class.getResourceAsStream("/serverWhiteList.json")),

                    new TypeToken<List<String>>() {

                    }.getType());

        } catch (Exception e) {

            e.printStackTrace();

        }

    }

    /**

     * 判斷目前host是否在白名單内

     * @param host 待查host

     * @return boolean 是否在白名單内

     */

    public static boolean isWhite(String host) {

        if (whiteList == null || whiteList.size() == 0) {

            return true;

        }

        for (String str : whiteList) {

            if (str != null && str.equals(host)) {

                return true;

            }

        }

        return false;

    }

}