Request.Url.Host 偽造實驗

我有個 IIS 網站同時繫結多個 IP,想做到依據連上的伺服器 IP 授與不同權限,例如: 有些功能開放外網 IP 連入使用,某些功能限定內網及 localhost IP 才能用。設立兩個站台繫結不同 IP 及 Port 但共用同一份 ASP.NET 程式碼是一種解法,但我貪圖共用 Process 及靜態物件的便利性,因此要研究正確識別 Request 伺服器來源 IP 的方法。

舉最簡單的例子,IIS 預設繫結到所有 IP 位址("*"),而若伺服器 IP 為 172.28.1.1,則使用者用 httq://127.0.0.1、httq://localhost、httq://172.28.1.1 連上的都是同一站台。

如果不花腦筋,Request.Url.Host 會依瀏覽器輸入的 URL 分別傳回 127.0.0.1、localhost、172.28.1.1,似乎可用。但仔細想想不對! Host 資訊由 Request 內容決定,可能會被偽造,萬萬不可做為資安或權限管控依據。

查了文件,IIS 提供的 ServerVariables 變數裡有個 LOCAL_ADDR:

Returns the server address on which the request came in. This is important on computers where there can be multiple IP addresses bound to the computer, and you want to find out which address the request used.

LOCAL_ADDR 位址由 IIS 決定,是較可靠的來源。

我寫了以下程式實測:

    public class HomeController : Controller
    {
        // GET: Home
        public ActionResult Index()
        {
            return Content($@"
Url.Host={Request.Url.Host},
LOCAL_ADDR={Request.ServerVariables["LOCAL_ADDR"]}");
        }
    }

使用瀏覽器測試,Url.Host 與 LOCAL_ADDR 都會依網址傳回不同結果,足以區別使用者連上的伺服器 IP:

不過,瀏覽器測試 OK 不代表不能做壞事,花一點點功夫寫幾行程式(註: 用 curl 工具甚至連程式都不必寫),靠著偽造 Host Header 輕鬆騙過 Rquest.Url.Host,想指定為任何字串都成:

經以上實驗證明,Request.Url.Host 不可信,不建議用於安全管控,ServerVariables LOCAL_ADDR、SERVER_PORT 是較好的選擇。

歡迎推文分享:
Published 11 January 2018 09:42 PM 由 Jeffrey
Views: 4,691



意見

沒有意見

你的看法呢?

(必要的) 
(必要的) 
(選擇性的)
(必要的) 
(提醒: 因快取機制,您的留言幾分鐘後才會顯示在網站,請耐心稍候)

5 + 3 =

搜尋

Go

<January 2018>
SunMonTueWedThuFriSat
31123456
78910111213
14151617181920
21222324252627
28293031123
45678910
 
RSS
創用 CC 授權條款
【廣告】
twMVC

Tags 分類檢視
關於作者

一個醉心技術又酷愛分享的Coding魔人,十年的IT職場生涯,寫過系統、管過專案, 也帶過團隊,最後還是無怨無悔地選擇了技術鑽研這條路,近年來則以做一個"有為的中年人"自許。

文章典藏
其他功能

這個部落格


Syndication