[ASP.Net] 過濾輸入欄位,可能具有危險的字串
在ASP.Net中,如果在任何Input欄位中輸入包含特定字元的字串(Ex.<script type="text/javascript">),會跳出錯誤訊息如下:
具有潛在危險 Request.Form 的值已從用戶端 (Text_Input="<script type="text/j...") 偵測到。
我們可以參考MSDN中,關於HttpRequestValidationException的描述:
當從用戶端收到的要求資料中可能有包含惡意的輸入字串時,會擲回的異常狀況。
ASP.Net很貼心的替我們判斷了輸入的字串中,是否具有造成危險的特定符號,
這是為了預防指令碼攻擊 (Ex. XSS),可能會造成系統安全上的漏洞,所做的保護。
而通常遇到這種情況,很多人會直接設定 ValidateRequest="false" ,來讓網站可以正常運行不會跳出錯誤,但如此一來,系統就存在了很有可能被攻擊的危險!
所以,為了避免跳出Exception,我們可以使用Page_Error Event,
來判斷目前所接受到的Exception是否為HttpRequestValidationException,
如果是的話,就跳出提示訊息,並且回到前一頁。
首先,我們替Page創建一個基本類別BasePage,並覆寫Page_OnError事件,
如此一來我們只需要將有輸入欄位需求的Page都繼承自BasePage,就可以同時套用到每個頁面!
BasePage.cs
using System;
using System.Web;
public class BasePage : System.Web.UI.Page
{
protected override void OnError(EventArgs e)
{
base.OnError(e);
Exception ex = Server.GetLastError();
if (ex is HttpRequestValidationException)
{
Server.ClearError();
string js = "<script type='text/javascript'>" +
"alert('請勿嘗試輸入具有危險性的字元!');" +
"history.go(-1);" +
"</script>";
Response.Write(js);
}
}
}
如此一來,當我們在TextBox輸入可能具有危險性的字串時,
就會跳出錯誤訊息,並回到前一頁,
那如果遇到真的需要讓使用者輸入包含HTML格式的字串時,又該怎麼辦呢?
我會推薦各位使用Microsoft Anti-Cross Site Scripting Library V3.1
它可以替我們過濾掉大部份具有危險性的字串,還原成較為安全的HTML語法,
建議大家在將可能具有危險性的字串,輸出至頁面或存入資料庫時,先對字串進行過濾。
為了方便使用,我替String寫了一個extention methods,來讓使用上更為方便快速!
public static class StringExtensions
{
public static string ToSafeHtml(this string str)
{
return AntiXss.GetSafeHtmlFragment(str);
}
}
使用方法如下:
string input = Textbox_Input.Text.ToSafeHtml();
參考資料:
- How To: Prevent Cross-Site Scripting in ASP.NET
- 推薦使用 Microsoft Anti-Cross Site Scripting Library v3.1
- Script Exploits Overview
- 善用 ASP.NET 內建功能來擊退網路攻擊
p.s. 目前我在專案中嘗試Reference AntiXSSLibrary.dll時,專案都會自動關閉,但執行Sample solution時卻沒有這個問題,不知道有沒有人遇過這種情況呢?