http://www.aygfsteel.com/ebecket 返還網(wǎng)
          隨筆-140  評論-11  文章-131  trackbacks-0
          asp.net開發(fā)中,經(jīng)常遇到“從客戶端檢測到有潛在危險(xiǎn)的Request.Form 值”錯(cuò)誤提示,很多人給出的解決方案是:

          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" %>

          其實(shí)這樣做是不正確的,會給程序安全帶來風(fēng)險(xiǎn)。

            ASP.Net 1.1后引入了對提交表單自動檢查是否存在XSS(跨站腳本攻擊)的能力。當(dāng)用戶試圖用之類的輸入影響頁面返回結(jié)果的時(shí)候,ASP.Net的引擎會引發(fā)一個(gè) HttpRequestValidationExceptioin。這是ASP.Net提供的一個(gè)很重要的安全特性。因?yàn)楹芏喑绦騿T對安全沒有概念,甚至都不知道XSS這種攻擊的存在,知道主動去防護(hù)的就更少了。ASP.Net在這一點(diǎn)上做到默認(rèn)安全。這樣讓對安全不是很了解的程序員依舊可以寫出有一定安全防護(hù)能力的網(wǎng)站。

            但是,當(dāng)我Google搜索 HttpRequestValidationException 或者 "A potentially dangerous Request.Form value was detected from the client"的時(shí)候,驚奇的發(fā)現(xiàn)大部分人給出的解決方案竟然是在ASP.Net頁面描述中通過設(shè)置 validateRequest=false 來禁用這個(gè)特性,而不去關(guān)心那個(gè)程序員的網(wǎng)站是否真的不需要這個(gè)特性。看得我這叫一個(gè)膽戰(zhàn)心驚。安全意識應(yīng)該時(shí)時(shí)刻刻在每一個(gè)程序員的心里,不管你對安全的概念了解多少,一個(gè)主動的意識在腦子里,你的站點(diǎn)就會安全很多。

            為什么很多程序員想要禁止 validateRequest 呢?有一部分是真的需要用戶輸入"<>"之類的字符。這就不必說了。還有一部分其實(shí)并不是用戶允許輸入那些容易引起XSS的字符,而是討厭這種報(bào)錯(cuò)的形式,畢竟一大段英文加上一個(gè)ASP.Net典型異常錯(cuò)誤信息,顯得這個(gè)站點(diǎn)出錯(cuò)了,而不是用戶輸入了非法的字符,可是自己又不知道怎么不讓它報(bào)錯(cuò),自己來處理報(bào)錯(cuò)。

            對于希望很好的處理這個(gè)錯(cuò)誤信息,而不使用默認(rèn)ASP.Net異常報(bào)錯(cuò)信息的程序員們,你們不要禁用validateRequest=false。

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

            舉例而言,處理這個(gè)異常其實(shí)只需要很簡短的一小段代碼就夠了。在頁面的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();
          }
          }
          這樣這個(gè)程序就可以截獲 HttpRequestValidationException 異常,而且可以按照程序員的意愿返回一個(gè)合理的報(bào)錯(cuò)信息。

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

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

            關(guān)于存在Rich Text Editor的頁面應(yīng)該如何處理?

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

            根據(jù)微軟的建議,我們應(yīng)該采取安全上稱為“默認(rèn)禁止,顯式允許”的策略。

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

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


          void submitBtn_Click(object sender, EventArgs e)
          {
          //將輸入字符串編碼,這樣所有的HTML標(biāo)簽都失效了。
          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標(biāo)簽,又禁止了危險(xiǎn)的標(biāo)簽。

          根據(jù)微軟提供的建議,我們要慎重允許下列HTML標(biāo)簽,因?yàn)檫@些HTML標(biāo)簽都是有可能導(dǎo)致跨站腳本攻擊的。


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


          可能這里最讓人不能理解的是<img>。但是,看過下列代碼后,就應(yīng)該明白其危險(xiǎn)性了。
          <img src="javascript:alert('hello');">
          posted on 2009-10-16 14:17 becket_zheng 閱讀(271) 評論(0)  編輯  收藏 所屬分類: web前端開發(fā)
          主站蜘蛛池模板: 英山县| 军事| 宁夏| 昌黎县| 兴宁市| 邵阳县| 白山市| 安多县| 长治市| 县级市| 忻州市| 台江县| 景泰县| 靖远县| 同心县| 任丘市| 枣强县| 西宁市| 芒康县| 红安县| 寿宁县| 藁城市| 桃园县| 子长县| 沾化县| 克什克腾旗| 江北区| 常山县| 铜山县| 景宁| 开平市| 林甸县| 田阳县| 民和| 松溪县| 南部县| 徐州市| 全州县| 蒙山县| 丹巴县| 乌兰县|