1. 程式人生 > >從客戶端(...)中檢測到有潛在危險的Request.Form 值的處理辦法

從客戶端(...)中檢測到有潛在危險的Request.Form 值的處理辦法

解決方案一: 
在.aspx檔案頭中加入這句: 
<%@ Page validateRequest="false"  %> 
解決方案二: 
修改web.config檔案: 
<configuration> 
  <system.web> 
    <pages validateRequest="false" /> 
  </system.web> 
</configuration> 
因為validateRequest預設值為true。只要設為false即可。
解決方法
若要在配置檔案中設定此值,可以為 httpRuntime
元素的 requestValidationMode 特性賦值。
在<system.web>節配置
<httpRuntimerequestValidationMode="2.0"/>
從客戶端檢測到有潛在危險的Request.Form值

asp.net開發中,經常遇到“從客戶端檢測到有潛在危險的Request.Form 值”錯誤提示,很多人給出的解決方案是:

1、web.config文件<system.web>後面加入這一句: <pages validaterequest="false"/>  示例:  <?xml version="1.0" encoding="gb2312" ?>  <configuration>  <system.web>  <pages validaterequest="false"/>  </system.web>  </configuration>

2、在*.aspx文件頭的page中加入validaterequest="false",示例如下:  <%@ page validaterequest="false" language="c#" codebehind="index.aspx.cs" autoeventwireup="false" inherits="mybbs.webform1" %> 

其實這樣做是不正確的,會給程式安全帶來風險。

  ASP.Net 1.1後引入了對提交表單自動檢查是否存在XSS(跨站指令碼攻擊)的能力。當用戶試圖用之類的輸入影響頁面返回結果的時候,ASP.Net的引擎會引發一個 HttpRequestValidationExceptioin。這是ASP.Net提供的一個很重要的安全特性。因為很多程式設計師對安全沒有概念,甚至都不知道XSS這種攻擊的存在,知道主動去防護的就更少了。ASP.Net在這一點上做到預設安全。這樣讓對安全不是很瞭解的程式設計師依舊可以寫出有一定安全防護能力的網站。

  但是,當我Google搜尋 HttpRequestValidationException 或者 "A potentially dangerous Request.Form value was detected from the client"的時候,驚奇的發現大部分人給出的解決方案竟然是在ASP.Net頁面描述中通過設定 validateRequest=false 來禁用這個特性,而不去關心那個程式設計師的網站是否真的不需要這個特性。看得我這叫一個膽戰心驚。安全意識應該時時刻刻在每一個程式設計師的心裡,不管你對安全的概念瞭解多少,一個主動的意識在腦子裡,你的站點就會安全很多。

  為什麼很多程式設計師想要禁止 validateRequest 呢?有一部分是真的需要使用者輸入"<>"之類的字元。這就不必說了。還有一部分其實並不是使用者允許輸入那些容易引起XSS的字元,而是討厭這種報錯的形式,畢竟一大段英文加上一個ASP.Net典型異常錯誤資訊,顯得這個站點出錯了,而不是使用者輸入了非法的字元,可是自己又不知道怎麼不讓它報錯,自己來處理報錯。

  對於希望很好的處理這個錯誤資訊,而不使用預設ASP.Net異常報錯資訊的程式設計師們,你們不要禁用validateRequest=false。

  正確的做法是在你當前頁面新增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標籤,又禁止了危險的標籤。

根據微軟提供的建議,我們要慎重允許下列HTML標籤,因為這些HTML標籤都是有可能導致跨站指令碼攻擊的。


<applet> 
<body> 
<embed> 
<frame> 
<script> 
<frameset> 
<html> 
<iframe> 
<img> 
<style> 
<layer> 
<link> 
<ilayer> 
<meta> 
<object>


可能這裡最讓人不能理解的是<img>。但是,看過下列程式碼後,就應該明白其危險性了。
<img src="javascript:alert('hello');">

MVC3: FormCollection collection =newFormCollection(Request.Unvalidated().Form);