ELMAH是一個優秀的ASP.NET錯誤記錄模組,安裝簡便,只需將elmah.dll放到bin目錄下,再適當修改web.config,ELMAH就能在ASP.NET發生例外錯誤(Exception)時,將錯誤訊息、程式碼位置、Query String、Cookie、Client IP、登入身分... 等等偵錯資訊鉅細靡遺地保存下來,並且還提供了網頁查詢介面,可直接透過網站調閱每一則錯誤的細節。

安裝ELMAH後,我們可以設定customErrors,在ASP.NET出錯時,顯示較友善的錯誤訊息給使用者,又同時保存錯誤細節(因為使用者看不到,不必擔心程式碼位置等資訊外洩),供系統管理人員或開發人員事後追查。關於錯誤資訊的保存,ELMAH支援了 XML檔案、SQL/ORACLE/SQLLite/Access/MySQL資料庫... 等格式,還能提供Email通知,功能頗為完整。

關於ELMAH的安裝與功能,已有好幾位朋友PO過中文介紹(RiCodemoPete .NET),在此不在多加闡述,僅針對elmah.axd的查詢權限設定做些補充。

預設設定下,elmah.axd並非做太多資安管控,任何人輸入http: //server/elmah.axd都可以檢視錯誤清單。所以一般會透過<security allowRemoteAccess="0" />限定本機查詢,或是利用ASP.NET的<authorization>設定限定非匿名使用者或特定使用者才能存取。常見的寫法如下:

<location path="elmah.axd">
  <system.web>
    <authorization>
      <deny users="?"/>
    </authorization>
  </system.web>
</location>

實地驗證了一下,這種做法有點問題。由於HttpHandler指定的Path會被視為相對網址,換句話說,不管http: //server/elmah.axd 或 http: //server/blah/elmah.axd都可順利存取elmah.axd檢視錯誤。使用location path="elmah.axd"設定只能限定http: //server/elmah.axd必須登入使用,有心人士若在URL上加點料,隨便改成http: //server/whatever/elmah.axd,就能輕鬆繞過安檢哨,大大方方地欣賞網站茶包,挺危險的!

【2011-03-11補充】ASP.NET MVC專案預設會使用/control/action的Routing規則解析URL,/*/elmah.axd被視為無效網址,較無被亂入的危險,但是/a/a/a/elmah.axd的形式就可繞過MVC Routing規則,一樣會有危險。(感謝demo分享)

經過爬文與測試,參考stackoverflow的一篇討論,我試擬了一個較安全的設定方式:

  1. 移除原本system.web / httpHandlers (for IIS 6) 及 system.webServer / handlers (for IIS7) 下的<add name="Elmah" verb="POST,GET,HEAD" path="elmah.axd" type="Elmah.ErrorLogPageFactory, Elmah" /> 。防止使用者透過http: //server/*/*/elmah.axd等隨意路徑闖入查詢畫面。
  2. 在<configuration>加入以下設定(以ASP.NET搭配Windows認證為例)
      <location path="debugger">
        <system.webServer>
          <handlers>
            <add name="Elmah" verb="POST,GET,HEAD" path="elmah_blah.axd" 
                 type="Elmah.ErrorLogPageFactory, Elmah" />
          </handlers>
        </system.webServer>
        <system.web>
          <httpHandlers>
            <add name="Elmah" verb="POST,GET,HEAD" path="elmah_blah.axd" 
                 type="Elmah.ErrorLogPageFactory, Elmah" />
          </httpHandlers>
          <authorization>
            <allow users="DOMAIN\User1, DOMAIN\User2" />
            <allow roles="BUILTIN\Administrators"/>
            <deny users="*" />
          </authorization>
        </system.web>
      </location>

如此,我們可以限定只有使用http: //server/debugger/elmah_blah.axd(或/debugger/*/elmah_blah.axd)才能檢視ELMAH的網頁查詢網頁,而整個debugger目錄限定特定使用者(如: DOMAIN\User1, DOMAIN\User2)或群組(如: BUILTIN\Administrators)可以存取。另外,debugger路徑及elmah_blah.axd可以取成特殊的命名,降低被猜中的機率。

經過上述設定後,應該可以產生不錯的保護效果,如果還有疏漏不足之處,歡迎指教交流。


Comments

# by rex

根據黑大以上的作法,在mvc測試這樣的連結都找不到資源檔,無效 http: //server/debugger/elmah_blah.axd 但在webform就沒問題,不知路徑跟route是不是那邊有問題?

# by Will 保哥

關於【2011-03-11補充】的問題,只要加上一個斜線(/)就能解決,無須取成特殊的命名。 <add name="Elmah" verb="POST,GET,HEAD" path="/elmah.axd" type="Elmah.ErrorLogPageFactory, Elmah" />

# by Jeffrey

to 保哥, 關於path=&quot;/elmah.axd&quot;,當初嘗試的結果,有一個小限制是要配合Web Application所安裝的路徑,例如: 當整個Web App被掛在httq://localhost/MyApp下時,須寫成path=&quot;/MyApp/elmah.axd&quot;,因此部署後要記得調整。另外,取特殊命名,即便安全性因意外沒設定好,仍具有不會被人以慣用命名猜中連上來偷看的好處(雖然只適用在僥倖的場合,但多一分安全無妨)。

# by Will 保哥

to Jeffrey: 僥倖之心不可有,防人之心不可無,最好兩個都一起設定最安全。呵~ (資安的偏執)

# by 小馬

請問黑哥,這個工具可否架設於 asp.net 網站

# by Jeffrey

to 小馬, elmah可安裝於ASP.NET Web Application下運作,沒問題的。

# by rex

「但在webform就沒問題,不知路徑跟route是不是那邊有問題?」 對mvc不熟,知道是為什麼了 預設只有 routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 加入 routes.IgnoreRoute("debugger/{resource}.axd/{*pathInfo}"); 自訂的httpHandlers才處理的到 另外下列httpHandlers好像沒有name的attribute,vs會提示錯誤 <add name="Elmah" verb="POST,GET,HEAD" path="elmah_blah.axd" type="Elmah.ErrorLogPageFactory, Elmah" />

# by James

如果想將ELMAH整合在自己的後台管理,不想在進入ELMAH時還要Windows認證一次,有什麼利用Session之類的單點登入解決方案嗎?

# by Jeffrey

to James,ELMAH使用web.config的authorization設定來管控身份,應可直接引用ASP.NET Form驗證的使用者及角色設定(前題是你的後台也是用它來管理身分),若是Windows驗證,則可以考慮設定IE自動登入省卻登入的步驟。

# by James

如果參考MSDN的"Forms 身份驗證"寫法 http://msdn.microsoft.com/zh-cn/library/xdt4thhy(v=vs.80).aspx#Y3120 那麼有關ELMAH在authorization區段的程式碼是否改為以下的寫法即可? <authentication mode="Forms"> <forms loginUrl="Logon.aspx" name=".ASPXFORMSAUTH"> </forms> <deny users="*" /> </authentication>

# by Jeffrey

to James, authentication與authorization是兩個不同的設定區段,不應混在一起。關於這部分,小喵大有個錄影教學介紹,不妨參考看看: http://www.dotblogs.com.tw/topcat/archive/2008/06/02/4201.aspx

# by Jero

黑哥,請問一下,在本機(Server)上使用是正常可看到內容(http: //server/debugger/elmah_blah.axd),但,若是用別台機器(Client)來連時,就會無法存取,請問是需要另外再設定什麼嗎?

# by Jero

目前我是先用 IIS URL Rewrite Module 讓ASP.NET認為是本機IP 127.0.0.1才能顯示,不知是否有較好的方法 Orz

# by Jeffrey

to Jero, ELMAH有個設定<security allowRemoteAccess="0" />可限定只能由本機查詢,你的情境會不會是停用了遠端存取?

# by Jero

真是太感謝了,因為預設是0,所以就忽略了,補上並設定為1就可以了,謝謝^^

Post a comment