很多 ASP.NET MVC 開發者都會寫出高性能的代碼,很好地交付軟體,等等。但是卻並沒有安全性方面的計劃。 有一種攻擊是攻擊者截獲最終用戶提交的表單數據,將其改變再將修改後的數據發送到伺服器。 對於這種情況,開發者需要進行適當的驗證,不過驗證顯示的大量錯誤信息中可能會泄漏伺服器信息。 如常見的4 ...
很多 ASP.NET MVC 開發者都會寫出高性能的代碼,很好地交付軟體,等等。但是卻並沒有安全性方面的計劃。
有一種攻擊是攻擊者截獲最終用戶提交的表單數據,將其改變再將修改後的數據發送到伺服器。
對於這種情況,開發者需要進行適當的驗證,不過驗證顯示的大量錯誤信息中可能會泄漏伺服器信息。
如常見的404頁面和500頁面(俗稱黃頁):
解決方法:
- 先關閉自定義錯誤,將Web.config配置文件中customErrors節點的mode設置為Off
1 <system.web> 2 <customErrors mode="Off"></customErrors> 3 <compilation debug="true" targetFramework="4.5"/> 4 <httpRuntime targetFramework="4.5"/> 5 </system.web>
- 在GlobalFilter全局過濾器中取消HandleErrorAttribute的註冊
1 public class FilterConfig 2 { 3 public static void RegisterGlobalFilters(GlobalFilterCollection filters) 4 { 5 //filters.Add(new HandleErrorAttribute()); 6 } 7 8 }
- Global.asax文件並添加Application_Error事件代碼
1 protected void Application_Error(Object sender, EventArgs e) 2 { 3 Exception exception = Server.GetLastError(); 4 if (exception != null) 5 { 6 HttpException httpException = exception as HttpException; 7 if (httpException != null) 8 { 9 int errorCode = httpException.GetHttpCode(); 10 if (errorCode == 400 || errorCode == 404) 11 { 12 Response.StatusCode = 404; 13 Response.Redirect(string.Format("~/Error/Error404"), true); 14 Server.ClearError(); 15 return; 16 } 17 } 18 19 var postData = string.Empty; 20 try 21 { 22 using (System.IO.Stream stream = Request.InputStream) 23 { 24 using (System.IO.StreamReader streamReader = new System.IO.StreamReader(stream, System.Text.Encoding.UTF8)) 25 { 26 postData = streamReader.ReadToEnd(); 27 } 28 } 29 } 30 catch { } 31 32 //該方法為寫錯誤日誌和發送錯誤郵件給開發者的方法(可忽略) 33 LogCache.Instance.saveToLog(Request, AppDomain.CurrentDomain.BaseDirectory + @"\privateFolder\SysLog\Error\", DateTime.Now.ToString("yyyyMMddHH") + ".log", postData, exception.ToString()); 34 35 Response.StatusCode = 500; 36 Response.Redirect(string.Format("~/Error/Error500"), true); 37 Server.ClearError(); 38 } 39 }
- 添加自定義的404、500頁面
最終實現效果:
使用應用程式全局錯誤的一些優勢:
第一點就是相容性好,Web Form和MVC中都可以通用,如果舊的Web Form項目中是使用Application_Error處理全局異常,那麼在新的MVC項目就可以很容易移植過來!此外靈活性也比較高,相比ASP.NET自帶的自定義錯誤以及MVC的HandleError特性,可以更加自由的編寫靈活的業務代碼。
另外可以根據需求設定HTTP錯誤碼,這方面也是考慮到一個SEO的問題,畢竟ASP.NET的自定義錯誤機智是使用302重寫跳轉,並不有利於SEO。雖然customErrors節點的redirectMode屬性可以設置為"ResponseRewrite"(重寫),但是如果在跳轉的頁面上不設置HTTP錯誤碼,則HTTP狀態碼為200。
Application_Error處理網站異常的局限性:
Application_Error事件無法處理已經被處理的異常,比如在try-catch捕捉的異常。此外由於是應用程式級別的事件,所以無法處理操作方法或者控制器級別的異常,暫時我也只想到這些局限,一般來說只要項目沒有什麼特殊要求都可以使用此事件處理自定義異常。