從客戶端檢測(cè)到有潛在危險(xiǎn)的Request.Form值的asp.net代碼
更新時(shí)間:2009年03月05日 00:18:06 作者:
asp.net開(kāi)發(fā)中,經(jīng)常遇到“從客戶端檢測(cè)到有潛在危險(xiǎn)的Request.Form 值”錯(cuò)誤提示,很多人給出的解決方案是
1、web.config文檔<system.web>后面加入這一句:
<pages validaterequest="false"/>
示例:
XML/HTML
<?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í)這樣做是不正確的,會(huì)給程序安全帶來(lái)風(fēng)險(xiǎn)。
ASP.Net 1.1后引入了對(duì)提交表單自動(dòng)檢查是否存在XSS(跨站腳本攻擊)的能力。當(dāng)用戶試圖用之類的輸入影響頁(yè)面返回結(jié)果的時(shí)候,ASP.Net的引擎會(huì)引發(fā)一個(gè) HttpRequestValidationExceptioin。這是ASP.Net提供的一個(gè)很重要的安全特性。因?yàn)楹芏喑绦騿T對(duì)安全沒(méi)有概念,甚至都不知道XSS這種攻擊的存在,知道主動(dòng)去防護(hù)的就更少了。ASP.Net在這一點(diǎn)上做到默認(rèn)安全。這樣讓對(duì)安全不是很了解的程序員依舊可以寫出有一定安全防護(hù)能力的網(wǎng)站。
但是,當(dāng)我Google搜索 HttpRequestValidationException 或者 "A potentially dangerous Request.Form value was detected from the client"的時(shí)候,驚奇的發(fā)現(xiàn)大部分人給出的解決方案竟然是在ASP.Net頁(yè)面描述中通過(guò)設(shè)置 validateRequest=false 來(lái)禁用這個(gè)特性,而不去關(guān)心那個(gè)程序員的網(wǎng)站是否真的不需要這個(gè)特性??吹梦疫@叫一個(gè)膽戰(zhàn)心驚。安全意識(shí)應(yīng)該時(shí)時(shí)刻刻在每一個(gè)程序員的心里,不管你對(duì)安全的概念了解多少,一個(gè)主動(dòng)的意識(shí)在腦子里,你的站點(diǎn)就會(huì)安全很多。
為什么很多程序員想要禁止 validateRequest 呢?有一部分是真的需要用戶輸入"<>"之類的字符。這就不必說(shuō)了。還有一部分其實(shí)并不是用戶允許輸入那些容易引起XSS的字符,而是討厭這種報(bào)錯(cuò)的形式,畢竟一大段英文加上一個(gè)ASP.Net典型異常錯(cuò)誤信息,顯得這個(gè)站點(diǎn)出錯(cuò)了,而不是用戶輸入了非法的字符,可是自己又不知道怎么不讓它報(bào)錯(cuò),自己來(lái)處理報(bào)錯(cuò)。
對(duì)于希望很好的處理這個(gè)錯(cuò)誤信息,而不使用默認(rèn)ASP.Net異常報(bào)錯(cuò)信息的程序員們,你們不要禁用validateRequest=false。
正確的做法是在你當(dāng)前頁(yè)面添加Page_Error()函數(shù),來(lái)捕獲所有頁(yè)面處理過(guò)程中發(fā)生的而沒(méi)有處理的異常。然后給用戶一個(gè)合法的報(bào)錯(cuò)信息。如果當(dāng)前頁(yè)面沒(méi)有Page_Error(),這個(gè)異常將會(huì)送到Global.asax的Application_Error()來(lái)處理,你也可以在那里寫通用的異常報(bào)錯(cuò)處理函數(shù)。如果兩個(gè)地方都沒(méi)有寫異常處理函數(shù),才會(huì)顯示這個(gè)默認(rèn)的報(bào)錯(cuò)頁(yè)面呢。
舉例而言,處理這個(gè)異常其實(shí)只需要很簡(jiǎn)短的一小段代碼就夠了。在頁(yè)面的Code-behind頁(yè)面中加入這么一段代碼:
protected void Page_Error(object sender, EventArgs e)
{
Exception ex = Server.GetLastError();
if (HttpContext.Current.Server.GetLastError() is HttpRequestValidationException)
{
HttpContext.Current.Response.Write("請(qǐng)輸入合法的字符串【<a href=\"javascript:history.back(0);\">返回</a>】");
HttpContext.Current.Server.ClearError();
}
}
這樣這個(gè)程序就可以截獲 HttpRequestValidationException 異常,而且可以按照程序員的意愿返回一個(gè)合理的報(bào)錯(cuò)信息。
這段代碼很簡(jiǎn)單,所以我希望所有不是真的要允許用戶輸入之類字符的朋友,千萬(wàn)不要隨意的禁止這個(gè)安全特性,如果只是需要異常處理,那么請(qǐng)用類似于上面的代碼來(lái)處理即可。
而對(duì)于那些通過(guò) 明確禁止了這個(gè)特性的程序員,自己一定要明白自己在做什么,而且一定要自己手動(dòng)的檢查必須過(guò)濾的字符串,否則你的站點(diǎn)很容易引發(fā)跨站腳本攻擊。
關(guān)于存在Rich Text Editor的頁(yè)面應(yīng)該如何處理?
如果頁(yè)面有富文本編輯器的控件的,那么必然會(huì)導(dǎo)致有類的HTML標(biāo)簽提交回來(lái)。在這種情況下,我們不得不將validateRequest="false"。那么安全性怎么處理?如何在這種情況下最大限度的預(yù)防跨站腳本攻擊呢?
根據(jù)微軟的建議,我們應(yīng)該采取安全上稱為“默認(rèn)禁止,顯式允許”的策略。
首先,我們將輸入字符串用 HttpUtility.HtmlEncode()來(lái)編碼,將其中的HTML標(biāo)簽徹底禁止。
然后,我們?cè)賹?duì)我們所感興趣的、并且是安全標(biāo)簽,通過(guò)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("<b>", "<b>");
sb.Replace("</b>", "</b>");
sb.Replace("<i>", "<i>");
sb.Replace("</i>", "</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>。但是,看過(guò)下列代碼后,就應(yīng)該明白其危險(xiǎn)性了。
<img src="javascript:alert('hello');">
復(fù)制代碼 代碼如下:
<pages validaterequest="false"/>
示例:
XML/HTML
復(fù)制代碼 代碼如下:
<?xml version="1.0" encoding="gb2312" ?>
<configuration>
<system.web>
<pages validaterequest="false"/>
</system.web>
</configuration>
2、在*.aspx文檔頭的page中加入validaterequest="false",示例如下:
復(fù)制代碼 代碼如下:
<%@ page validaterequest="false" language="c#" codebehind="index.aspx.cs" autoeventwireup="false" inherits="mybbs.webform1" %>
其實(shí)這樣做是不正確的,會(huì)給程序安全帶來(lái)風(fēng)險(xiǎn)。
ASP.Net 1.1后引入了對(duì)提交表單自動(dòng)檢查是否存在XSS(跨站腳本攻擊)的能力。當(dāng)用戶試圖用之類的輸入影響頁(yè)面返回結(jié)果的時(shí)候,ASP.Net的引擎會(huì)引發(fā)一個(gè) HttpRequestValidationExceptioin。這是ASP.Net提供的一個(gè)很重要的安全特性。因?yàn)楹芏喑绦騿T對(duì)安全沒(méi)有概念,甚至都不知道XSS這種攻擊的存在,知道主動(dòng)去防護(hù)的就更少了。ASP.Net在這一點(diǎn)上做到默認(rèn)安全。這樣讓對(duì)安全不是很了解的程序員依舊可以寫出有一定安全防護(hù)能力的網(wǎng)站。
但是,當(dāng)我Google搜索 HttpRequestValidationException 或者 "A potentially dangerous Request.Form value was detected from the client"的時(shí)候,驚奇的發(fā)現(xiàn)大部分人給出的解決方案竟然是在ASP.Net頁(yè)面描述中通過(guò)設(shè)置 validateRequest=false 來(lái)禁用這個(gè)特性,而不去關(guān)心那個(gè)程序員的網(wǎng)站是否真的不需要這個(gè)特性??吹梦疫@叫一個(gè)膽戰(zhàn)心驚。安全意識(shí)應(yīng)該時(shí)時(shí)刻刻在每一個(gè)程序員的心里,不管你對(duì)安全的概念了解多少,一個(gè)主動(dòng)的意識(shí)在腦子里,你的站點(diǎn)就會(huì)安全很多。
為什么很多程序員想要禁止 validateRequest 呢?有一部分是真的需要用戶輸入"<>"之類的字符。這就不必說(shuō)了。還有一部分其實(shí)并不是用戶允許輸入那些容易引起XSS的字符,而是討厭這種報(bào)錯(cuò)的形式,畢竟一大段英文加上一個(gè)ASP.Net典型異常錯(cuò)誤信息,顯得這個(gè)站點(diǎn)出錯(cuò)了,而不是用戶輸入了非法的字符,可是自己又不知道怎么不讓它報(bào)錯(cuò),自己來(lái)處理報(bào)錯(cuò)。
對(duì)于希望很好的處理這個(gè)錯(cuò)誤信息,而不使用默認(rèn)ASP.Net異常報(bào)錯(cuò)信息的程序員們,你們不要禁用validateRequest=false。
正確的做法是在你當(dāng)前頁(yè)面添加Page_Error()函數(shù),來(lái)捕獲所有頁(yè)面處理過(guò)程中發(fā)生的而沒(méi)有處理的異常。然后給用戶一個(gè)合法的報(bào)錯(cuò)信息。如果當(dāng)前頁(yè)面沒(méi)有Page_Error(),這個(gè)異常將會(huì)送到Global.asax的Application_Error()來(lái)處理,你也可以在那里寫通用的異常報(bào)錯(cuò)處理函數(shù)。如果兩個(gè)地方都沒(méi)有寫異常處理函數(shù),才會(huì)顯示這個(gè)默認(rèn)的報(bào)錯(cuò)頁(yè)面呢。
舉例而言,處理這個(gè)異常其實(shí)只需要很簡(jiǎn)短的一小段代碼就夠了。在頁(yè)面的Code-behind頁(yè)面中加入這么一段代碼:
復(fù)制代碼 代碼如下:
protected void Page_Error(object sender, EventArgs e)
{
Exception ex = Server.GetLastError();
if (HttpContext.Current.Server.GetLastError() is HttpRequestValidationException)
{
HttpContext.Current.Response.Write("請(qǐng)輸入合法的字符串【<a href=\"javascript:history.back(0);\">返回</a>】");
HttpContext.Current.Server.ClearError();
}
}
這樣這個(gè)程序就可以截獲 HttpRequestValidationException 異常,而且可以按照程序員的意愿返回一個(gè)合理的報(bào)錯(cuò)信息。
這段代碼很簡(jiǎn)單,所以我希望所有不是真的要允許用戶輸入之類字符的朋友,千萬(wàn)不要隨意的禁止這個(gè)安全特性,如果只是需要異常處理,那么請(qǐng)用類似于上面的代碼來(lái)處理即可。
而對(duì)于那些通過(guò) 明確禁止了這個(gè)特性的程序員,自己一定要明白自己在做什么,而且一定要自己手動(dòng)的檢查必須過(guò)濾的字符串,否則你的站點(diǎn)很容易引發(fā)跨站腳本攻擊。
關(guān)于存在Rich Text Editor的頁(yè)面應(yīng)該如何處理?
如果頁(yè)面有富文本編輯器的控件的,那么必然會(huì)導(dǎo)致有類的HTML標(biāo)簽提交回來(lái)。在這種情況下,我們不得不將validateRequest="false"。那么安全性怎么處理?如何在這種情況下最大限度的預(yù)防跨站腳本攻擊呢?
根據(jù)微軟的建議,我們應(yīng)該采取安全上稱為“默認(rèn)禁止,顯式允許”的策略。
首先,我們將輸入字符串用 HttpUtility.HtmlEncode()來(lái)編碼,將其中的HTML標(biāo)簽徹底禁止。
然后,我們?cè)賹?duì)我們所感興趣的、并且是安全標(biāo)簽,通過(guò)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("<b>", "<b>");
sb.Replace("</b>", "</b>");
sb.Replace("<i>", "<i>");
sb.Replace("</i>", "</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>。但是,看過(guò)下列代碼后,就應(yīng)該明白其危險(xiǎn)性了。
<img src="javascript:alert('hello');">
您可能感興趣的文章:
- Jquery中request和request.form和request.querystring的區(qū)別
- asp.net中“從客戶端中檢測(cè)到有潛在危險(xiǎn)的Request.Form值”錯(cuò)誤的解決辦法
- ASP.NET檢測(cè)到不安全 Request.Form 值解決方案匯總
- ASP.NET從客戶端中檢測(cè)到有潛在危險(xiǎn)的request.form值的3種解決方法
- 有潛在危險(xiǎn)的 Request.Form 值避免方法
- ASP.NET中Request.Form中文亂碼的解決方法
- asp.net 從客戶端中檢測(cè)到有潛在危險(xiǎn)的 Request.Form 值錯(cuò)誤解
- C# Request.Form用法案例詳解
相關(guān)文章
Springboot服務(wù)Docker化自動(dòng)部署的實(shí)現(xiàn)方法
這篇文章主要介紹了Springboot服務(wù)Docker化自動(dòng)部署的實(shí)現(xiàn)方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-03-03
HttpRequest Get和Post調(diào)用其他頁(yè)面的方法
HttpRequest Get和Post調(diào)用其他頁(yè)面的方法,需要的朋友可以參考一下2013-03-03
asp.net 用戶在線退出更新實(shí)現(xiàn)代碼
更新用戶是否在線?注銷用戶的話有三種情況:1.點(diǎn)擊退出,2.會(huì)話超時(shí),3.關(guān)閉瀏覽器2010-03-03
登錄時(shí)記住用戶名和密碼及cookie案例應(yīng)用
本文將實(shí)現(xiàn)登錄時(shí)記住用戶的帳號(hào)密碼,接下來(lái)我們來(lái)模擬一個(gè)登錄介面,要把這個(gè)登錄的信息記錄至Cookie,還要把Cookie的過(guò)期時(shí)間設(shè)置7天之后過(guò)期,感興趣的朋友可以參考下,希望本文對(duì)你的cookie學(xué)習(xí)有所幫助2013-01-01
.NetCore利用BlockingCollection實(shí)現(xiàn)簡(jiǎn)易消息隊(duì)列
這篇文章主要介紹了.NetCore利用BlockingCollection實(shí)現(xiàn)簡(jiǎn)易消息隊(duì)列,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-09-09

