HOW TO:顯示安全錯誤訊息
更新:2007 年 11 月
當應用程式顯示錯誤訊息時,不應將有助於惡意使用者攻擊系統的資訊送出。例如,如果應用程式嘗試登入資料庫失敗,不應顯示包含使用中使用者名稱的錯誤訊息。
有幾個方法可以控制錯誤訊息,包括下列項目:
將應用程式設定為不將詳細錯誤訊息顯示給遠端使用者 (遠端使用者是指在 Web 伺服器電腦上工作時沒有請求網頁的使用者)。您可選擇將錯誤重新導向至應用程式網頁中。
只要可行,將錯誤處理納入,並建構您自己的錯誤訊息。在錯誤處理常式中,可測試查看使用者是否為本機使用者,並據此反應。
在網頁或應用程式層級建立全域錯誤處理常式,用來攔截所有未經處理的例外狀況,並將其傳送到泛用錯誤網頁。如此一來,即使您無法預知問題,至少使用者將看不到例外狀況網頁。
將應用程式設定為對遠端使用者關閉錯誤
在應用程式的 Web.config 檔案中,對 customErrors 項目作以下變更:
將 mode 屬性 (Attribute) 設為 RemoteOnly (區分大小寫)。這樣做會將應用程式設定為只對本機使用者 (也就是指身為開發人員的您) 顯示詳細錯誤資訊。
也可以選擇將指向應用程式錯誤網頁的 defaultRedirect 屬性納入。
也可以選擇加入 <error> 項目,將特定錯誤重新導向至特定網頁。例如,可將標準 404 錯誤 (找不到網頁) 重新導向至您自己的應用程式網頁。
在下列程式碼中,示範了 Web.config 檔中的典型 customErrors 區塊。
<customErrors mode="RemoteOnly" defaultRedirect="AppErrors.aspx"> <error statusCode="404" redirect="NoSuchPage.aspx"/> <error statusCode="403" redirect="NoAccessAllowed.aspx"/> </customErrors>
若要加入錯誤處理
在任何可能產生錯誤的陳述式周圍,使用 try-catch 區塊。
可以選擇以 IsLocal 屬性測試本機使用者,並據以修改錯誤處理。值 127.0.0.1 等於 localhost,表示瀏覽器是在與 Web 伺服器相同的電腦上。
在下列程式碼中,示範了錯誤處理區塊。如果發生錯誤,工作階段狀態變數會和有關訊息的詳細資料一起載入,然後應用程式會顯示可讀取 Session 變數的網頁,並顯示錯誤 (這個錯誤是故意撰寫的,未提供使用者可擅用的詳細資訊)。如果是本機使用者,就會提供不同的錯誤詳細資料。在 finally 區塊中,釋放了開啟的資源。
Try SqlConnection1.Open() SqlDataAdapter1.Fill(Me.DsPubs1) Catch ex As Exception If Request.IsLocal Then Session("CurrentError") = ex.Message Else Session("CurrentError") = "Error processing page." End If Server.Transfer("ApplicationError.aspx") Finally SqlConnection1.Close() End Try
try { sqlConnection1.Open(); sqlDataAdapter1.Fill(dsCustomers1); } catch (Exception ex) { if(Request.IsLocal) { Session["CurrentError"] = ex.Message; } else { Session["CurrentError"] = "Error processing page."; } Server.Transfer("ApplicationError.aspx"); } finally { this.sqlConnection1.Close(); }
建立全域錯誤處理常式
也可以建立錯誤處理常式,在頁面層次或整個應用程式中攔截未處理的例外狀況。
若要建立全域錯誤處理常式
若要在網頁中建立全域處理常式,請建立 TemplateControl.Error 事件的處理常式。若要建立應用程式範圍的錯誤處理常式,請在 Global.asax 檔中,將程式碼加入 HttpApplication.Error 事件。如果在網頁或應用程式中的任何位置,分別發生未處理的例外狀況,則會呼叫這些方法。可從 GetLastError 方法中取得最近發生之錯誤的相關資訊。
注意事項: 如果您有全域錯誤處理常式,它的優先順序比在 customErrors 組態項目的 defaultRedirect 屬性中指定的錯誤處理高。
在下列程式碼中示範了一個處理常式,它會取得目前錯誤的相關資訊,將其放在 Session 變數中,接著呼叫可以擷取並顯示錯誤資訊的泛型錯誤處理網頁。
Sub Application_Error(ByVal sender As Object, ByVal e As EventArgs) Session("CurrentError") = "Global: " & _ Server.GetLastError.Message Server.Transfer("lasterr.aspx") End Sub
protected void Application_Error(Object sender, EventArgs e) { Session["CurrentError"] = "Global: " + Server.GetLastError().Message; Server.Transfer("lasterr.aspx"); }