HTTP Host Header 資安弱點
| | 2 | | ![]() |
同事分享資安知識一則:在網頁引用 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.Host
或 Request.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 部落格提供以下建議:
- 避免在程式中使用 Request.Url.Host 或 Request.Headers["Host"],應假設他們可能被偽造竄改,如要使用務必確實檢核
- 在 IIS Binding 限定 Host 名稱可防範這類攻擊,例如:
若攻擊者竄改 Host Header,將得到 404:
- 在 Reverse Proxy 情境會用 X-Forwarded-Host 取代 Host Header,請用相同標準看待,不要信任。
- 若不指定 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, 已校正,謝~