從客戶端XXX中檢測到有潛在危險的 Request.Form值——終極解決方案


說明:ASP.NET 在請求中檢測到包含潛在危險的數據,因為它可能包括 HTML 標記或腳本。該數據可能表示存在危及應用程序安全的嘗試,如跨站點腳本攻擊。如果此類型的輸入適用於您的應用程序,則可包括明確允許的網頁中的代碼。有關詳細信息,請參閱 http://go.microsoft.com/fwlink/?LinkID=212874。

異常詳細信息:System.Web.HttpRequestValidationException: 從客戶端(newsContent="<p>
后台測試后台測試</p>
")中檢測到有潛在危險的 Request.Form 值。

 

出現這個情況通常都是由於在表單中輸入了html標簽。ASP.Net 1.1后引入了對提交表單自動檢查是否存在XSS(跨站腳本攻擊)的能力。當用戶試圖用之類的輸入影響頁面返回結果的時候,ASP.Net的引擎會引發一個 HttpRequestValidationExceptioin。這是ASP.Net提供的一個很重要的安全特性。因為很多程序員對安全沒有概念,甚至都不知道XSS這種攻擊的存在,知道主動去防護的就更少了。ASP.Net在這一點上做到默認安全。這樣讓對安全不是很了解的程序員依舊可以寫出有一定安全防護能力的網站。

 

但是當某些特殊情況必須需要輸入這些標簽的時候就不希望報這個錯誤了。

 

於是就出現了下面些個解決方案。

 

解決方案一:
  在.aspx文件頭中加入這句:
<%@ Page validateRequest="false" %>

   如果是ASP.NET MVC項目則在對應的action上面加上

[ValidateInput(false)]

  解決方案二:
  修改web.config文件:
<configuration> 
    <system.web> 
        <pages validateRequest="false" /> 
    </system.web> 
</configuration>

  因為validateRequest默認值為true。只要設為false即可。

 

在ASP.NET4.0的情況下,需要注意一點是:在Web.Config文件中的配置節</system.web>之前加上如下一句配置

<httpRuntime requestValidationMode="2.0" />

 

 

另外,這些方法雖然可以解決問題,但是卻不是最佳的解決方案。

 

下面說說最好的方法

 

       正確的做法是在你當前頁面添加Page_Error()函數,來捕獲所有頁面處理過程中發生的而沒有處理的異常。然后給用戶一個合法的報錯信息。如果當前頁面沒有Page_Error(),這個異常將會送到Global.asax的Application_Error()來處理,你也可以在那里寫通用的異常報錯處理函數。如果兩個地方都沒有寫異常處理函數,才會顯示這個默認的報錯頁面呢。

  舉例而言,處理這個異常其實只需要很簡短的一小段代碼就夠了。在頁面的Code-behind頁面中加入這么一段代碼:

protected void Page_Error( object sender, EventArgs e)
{
   Exception ex
= Server.GetLastError();
if (HttpContext.Current.Server.GetLastError() is HttpRequestValidationException)
   {
       HttpContext.Current.Response.Write(
" 請輸入合法的字符串【<a href=\"javascript:history.back(0);\">返回</a>】 " );
       HttpContext.Current.Server.ClearError();
   }
}

  這樣這個程序就可以截獲 HttpRequestValidationException 異常,而且可以按照程序員的意願返回一個合理的報錯信息。

  這段代碼很簡單,所以我希望所有不是真的要允許用戶輸入之類字符的朋友,千萬不要隨意的禁止這個安全特性,如果只是需要異常處理,那么請用類似於上面的代碼來處理即可。

  而對於那些通過 明確禁止了這個特性的程序員,自己一定要明白自己在做什么,而且一定要自己手動的檢查必須過濾的字符串,否則你的站點很容易引發跨站腳本攻擊。

 

 

關於存在Rich Text Editor的頁面應該如何處理?

  如果頁面有富文本編輯器的控件的,那么必然會導致有類的HTML標簽提交回來。在這種情況下,我們不得不將validateRequest="false"。那么安全性怎么處理?如何在這種情況下最大限度的預防跨站腳本攻擊呢?

  根據微軟的建議,我們應該采取安全上稱為“默認禁止,顯式允許”的策略。

  首先,我們將輸入字符串用 HttpUtility.HtmlEncode()來編碼,將其中的HTML標簽徹底禁止。

  然后,我們再對我們所感興趣的、並且是安全標簽,通過Replace()進行替換。比如,我們希望有""標簽,那么我們就將""顯式的替換回""。

void submitBtn_Click( object sender, EventArgs e)
{
// 將輸入字符串編碼,這樣所有的HTML標簽都失效了。
   StringBuilder sb = new StringBuilder(HttpUtility.HtmlEncode(htmlInputTxt.Text));
// 然后我們選擇性的允許<b> 和 <i>
   sb.Replace( " &lt;b&gt; " , " <b> " );
   sb.Replace(
" &lt;/b&gt; " , " </b> " );
   sb.Replace(
" &lt;i&gt; " , " <i> " );
   sb.Replace(
" &lt;/i&gt; " , " </i> " );
   Response.Write(sb.ToString());
}

 

這樣我們即允許了部分HTML標簽,又禁止了危險的標簽。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM