同事分享資安知識一則:在網頁引用 Host Header 可能形成資安弱點,給予攻擊者操作重新導向或引用惡意程式的機會。特筆記備忘。

使用 IIS + ASP.NET 示範如下:

<%@Page Language="C#"%>
<html>
    <head>
        <title>Host Header 弱點示範</title>
    </head>
    <body>
        <ul>
            <li>Request.Url.Host = <%=Request.Url.Host%></li>
            <li>Request.Headers["Host"] = <%=Request.Headers["Host"]%></li>
        </ul>
        <!-- 危險做法:依 Host 決定網址, 可能被惡意竄改 -->
        <script src="://<%=Request.Url.Host%>/scripts/app.js"></script>
    </body>
</html>

在一般情況下,瀏覽器或 HTTP 客戶端開啟 https://blog.darkthread.net/ 時會帶入 Host: blog.darkthread.net,同樣是 80 Port,網站可依不同 Host 導向不同站台,實現多站台共用 80 Port 的效果。而伺服器端 ASP.NET 可由 Request.Url.HostRequest.Headers["Host"] 讀取 blog.darkthread.net。

以下使用 curl 工具觀察 Host Header 依 URL 改變的行為及伺服器端讀取結果:

curl -v http://localhost/aspnet45/vulnerable.aspx
curl -v http://127.0.0.1/aspnet45/vulnerable.aspx

但問題出在以上是標準行為,若瀏覽器或客戶端遭惡意軟體控制或傳輸過程遭攔截,Host 就可能被偷改。若伺服器端依據 Request.Url.Host 決定重導位址或是 JavaScript 載入位址,攻擊者便能上下其手,將使用者導向詐騙網站或下載惡意程式。例如以下範例,curl 送出請求時使用參數覆寫 Host Header,ASP.NET 將讀到有毒的值,若還拿來指定 JavaScript 下載位址就危險了。

curl -v http://localhost/aspnet45/vulnerable.aspx -H "Host: you-are-hacked.com"

針對這類風險,IIS 部落格提供以下建議:

  1. 避免在程式中使用 Request.Url.Host 或 Request.Headers["Host"],應假設他們可能被偽造竄改,如要使用務必確實檢核
  2. 在 IIS Binding 限定 Host 名稱可防範這類攻擊,例如:

    若攻擊者竄改 Host Header,將得到 404:
  3. 在 Reverse Proxy 情境會用 X-Forwarded-Host 取代 Host Header,請用相同標準看待,不要信任。
  4. 若不指定 Binding,可考慮使用 UrlRewrite 檢查 Host Header,發現被竄改時執行阻擋或重新導向。以下範例在 UrlRewrite 模組新增 Request Blocking Rule,比對 Host Header 不吻合 RegularExpression ^(127.0.0.1|localhost)$ 時傳回 403:

    實測也能阻擋偽造 Host Header:

Introduction to HTTP Host header attacks and how to prevent them.


Comments

# by Ming

curl -v http: //localhost/aspnet45/vulnerable.aspx -H "Header: you-are-hacked.com" 圖文不符 XD

# by Jeffrey

to Ming, 已校正,謝~

Post a comment


77 - 39 =