從 IIS Reponse Header 移除 Server、X-AspNet-Version、X-Powered-By 等版本資訊,可降低因曝露資訊被鎖定攻擊的機率,被視為提高資安防護的手段(效果高低見仁見智,但有些資安掃瞄將此列為弱點,不做也得做)。這已算是老話題,網路上有不少討論與參考文章:
- mrkt 的程式學習筆記- ASP.NET MVC - 移除特定的 Response Headers 內容
- Troy Hunt: Shhh… don’t let your response headers talk too loudly
- KingKong Bruce記事: 提升ASP.NET MVC專案安全性與效能小技巧
綜觀常見的幾種做法,不管是用 IHttpModule 或 Global.asax.cs 在 PreSendRequestHeader() 將 Server Header 移除,都只對 ASP.NET WebForm 或 ASP.NET MVC 有效,攻擊者只要改下載 HTML/JS/CSS/JPG/PNG 等靜態檔案,甚至隨便想個不存在的 html,HTTP 404 Reponse 冒出 Server: Microsoft-IIS/10.0 當場破功,白忙半天。
這是因為靜態內容由 IIS 直接處理,不會經過我們設計的機制(延伸閱讀:system.web 與 system.webServer)。
有個笨方法,設定 <modules runAllManagedModulesForAllRequests="true"> 將所有靜態檔案也導入 ASP.NET Pipeline,雖然管用,但原本由 IIS 輕巧做掉的工作通通被導進為複雜情境設計的笨重程序,對效能很傷。
Server Header 是當中最棘手的項目,IIS Manager HTTP Response Headers 或 URL Rewrite Module 可以改寫或清空 Server Header,但無法移除,而 UrlScan 可以清除 Server Header 只支援到 IIS 7。
最後我找到一個不錯的解決方案 - StripHeaders。一個 C++ 開發的開源模組,使用 WIN32 API 在 IIS 核心執行,能涵蓋靜態內容,核心模組的 Overhead 低,加上原生程式執行效能遠比 .NET 程式快,較不用擔心效能問題。
IIS 原生模組的安裝程序蠻多,不過 StripHeaders 提供 MSI 安裝檔,大大簡化安裝步驟。目前最新版 iis_stripheaders_module_1.0.5.msi 於 2016-11-19 推出,支援 Server 2016。
安裝程式在背後做了一堆事:
- Installs stripheaders.dll
- Registers the Native-Code module with IIS using the appcmd.exe command
- Extends the IIS configuration schema to allow setting of headers to remove
- Adds default settings to the IIS configuration to remove the common "Server", "X-Powered-By" and "X-Aspnet-Version" response headers
- Adds a registry setting to remove the "Server: Microsoft-HTTPAPI/2.0" response header.
理論上重開機後就會生效,如果你不想重開機,可以使用 net stop http 重啟底層 HTTP 服務再手動啟動 IIS 及其他相依服務。不過我實測時停用 HTTP 失敗(處於停用中的狀態,一直關不掉),最後只能重開機。但我遇的狀況是重開完也沒生效,最後參考 Github 的安裝程式原始碼(Open Source 萬歲!),手動註冊 StripHeadersModule 才解決問題:
安裝妥當後,如下圖應該要在 IIS 模組清單看到 StripHeadersModule:
StripHeaders 預設會移除 Server、X-Powered-By、X-AspNet-Version 等 Response Header,不需修改 web.config 就會生效。如需移除額外 Header,則可在 web.config system.webServer/stripHeaders 中設定。
以 css 實測,未啟用 StripHeaders 前:
啟用後,Server、X-Powered-By 消失,成功!