从客户端检测到有潜在危险的Request.Form值

asp.net开发中,经常遇到“从客户端检测到有潜在危险的Request.Form 值”错误提示,很多人给出的解决方案是:

一、常用的方法(看完本文后,请不要再使用这种方法)
1 <!--web.config文档<system.web>后面加入这一句: <pages validaterequest="false"/> 示例: -->
2 <?xml version="1.0" encoding="gb2312" ?> 
3 <configuration> 
4 <system.web> 
5 <pages validaterequest="false"/> 
6 </system.web> 
7 </configuration>
二、在*.aspx文档头的page中加入validaterequest="false",示例如下: (不推荐)
1 <%@ page validaterequest="false" language="c#" codebehind="index.aspx.cs" autoeventwireup="false" inherits="mybbs.webform1" %> 

   其实以上二点的做法都是不正确的,会给程序安全带来风险。

  首先出现这个错误的原因是,Asp.Net增加了表单自动检查是否存在XSS(跨站脚本攻击)的功能。当用户提交了非法的字符(如:在线编辑器中的一系列html结构)。出于安全考虑,Asp.Net是直接禁止的,并提示出错。这是ASP.Net提供的一个很重要的安全特性。

 

  不使用默认ASP.Net异常报错信息的程序员们,你们不要禁用validateRequest=false。

  正确的做法是在你当前页面添加Page_Error()函数,来捕获所有页面处理过程中发生的而没有处理的异常。然后给用户一个合法的报错信息。

  如果当前页面没有Page_Error(),这个异常将会送到Global.asax的Application_Error()来处理。

  举例而言,处理这个异常其实只需要很简短的一小段代码就够了。在页面的Code-behind页面中加入这么一段代码:

 1 protected void Page_Error(object sender, EventArgs e)
 2 
 3 {
 4 
 5   Exception ex = Server.GetLastError();
 6 
 7   if (HttpContext.Current.Server.GetLastError() is HttpRequestValidationException)
 8 
 9   {
10 
11     HttpContext.Current.Response.Write("请输入合法的字符串【<a href=\"javascript:history.back(0);\">返回</a>】");
12 
13     HttpContext.Current.Server.ClearError();
14 
15   }
16 
17 }

  这样这个程序就可以截获 HttpRequestValidationException 异常,而且可以按照程序员的意愿返回一个合理的报错信息。

 

  如果页面有富文本编辑器的控件的,那么必然会导致有类的HTML标签提交回来。在这种情况下根据微软的建议,我们应该采取安全上称为“默认禁止,显式允许”的策略。

  首先,我们将输入字符串用 HttpUtility.HtmlEncode()来编码,将其中的HTML标签彻底禁止。

三、安全的做法应该是对其进行编码处理(推荐)
 1 void submitBtn_Click(object sender, EventArgs e)
 2 {
 3 
 4 //将输入字符串编码,这样所有的HTML标签都失效了。
 5 
 6 StringBuilder sb = new StringBuilder(HttpUtility.HtmlEncode(htmlInputTxt.Text));
 7 
 8 //然后我们选择性的允许<b> 和 <i>
 9 
10 sb.Replace("&lt;b&gt;", "<b>");
11 sb.Replace("&lt;/b&gt;", "</b>");
12 sb.Replace("&lt;i&gt;", "<i>");
13 sb.Replace("&lt;/i&gt;", "</i>");
14 Response.Write(sb.ToString());
15 
16 }

这样我们即允许了部分HTML标签,又禁止了危险的标签。

根据微软提供的建议,我们要慎重允许下列HTML标签,因为这些HTML标签都是有可能导致跨站脚本攻击的。

 1 <applet> 
 2 <body> 
 3 <embed> 
 4 <frame> 
 5 <script> 
 6 <frameset> 
 7 <html> 
 8 <iframe> 
 9 <img> 
10 <style> 
11 <layer> 
12 <link> 
13 <ilayer> 
14 <meta> 
15 <object>

可能这里最让人不能理解的是<img>。但是,看过下列代码后,就应该明白其危险性了。
 1 <img src="javascript:alert('hello');"> 

 

posted @ 2009-07-09 11:04  steden  阅读(458)  评论(0编辑  收藏  举报