请慎用ASP.Net的validateRequest=“false”

asp.net|request

  ASP.Net 1.1后引入了对提交表单自动检查是否存在XSS(跨站脚本攻击)的能力。当用户试图用之类的输入影响页面返回结果的时候,ASP.Net的引擎会引发一个 HttpRequestValidationExceptioin。默认情况下会返回如下文字的页面:

Server Error in '/YourApplicationPath' Application

A potentially dangerous Request.Form value was detected from the client
(txtName="<b>").

Description: Request Validation has detected a potentially dangerous client input value, and processing of the request has been aborted. This value may indicate an attempt to compromise the security of your application, such as a cross-site scripting attack. You can disable request validation by setting validateRequest=false in the Page directive or in the configuration section. However, it is strongly recommended that your application explicitly check all inputs in this case.

Exception Details: System.Web.HttpRequestValidationException: A potentially dangerous Request.Form value was detected from the client (txtName="<b>").

....

  这是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 (ex is HttpRequestValidationException)
    {
        Response.Write("请您输入合法字符串。");
        Server.ClearError(); // 如果不ClearError()这个异常会继续传到Application_Error()。
    }
}

  这样这个程序就可以截获 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("<b>", "<b>");
    sb.Replace("</b>", "");
    sb.Replace("<i>", "<i>");
    sb.Replace("</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');">
<img src="java
script:alert('hello');">
<img src="java
script:alert('hello');">
  通过<img>标签是有可能导致Javascript执行的,这样攻击者就可以做他想伪装的任何事情。

  关于<style>也是一样:

<style TYPE="text/javascript">...
  alert('hello');
</style>

时间: 2024-09-19 23:55:22

请慎用ASP.Net的validateRequest=“false”的相关文章

IIS处理asp.net请求和asp.net的页面生命周期

当一个客户端页面访问IIS试图获取一些信息的时候,发生了什么事情?一个请求在通过了HTTP管道后又发生了什么?本文主要是描述这两个过程,即IIS处理asp.net请求和asp.net的页面生命周期.欢迎大家积极拍砖,共同学习,共同进步. 首先我们要弄清楚两个非常重要的概念: 1, worker process(w3wp.exe). worker process管理所有的来自客户端的请求并给出响应.它是IIS下asp.net应用程序的核心. 2, application pool. 它是worke

ValidateInput(false)与this.ValidateRequest = false无效的解决方案

ValidateInput(false)与this.ValidateRequest = false无效的解决方案 鼓捣了半天 终于解决了这个问题 写出来 叫后人少费点劲 在最外层的web.config中的 systerm.web节点中加入这么一句话 <httpRuntime requestValidationMode="2.0"/> 一切就OK了---  

出现乱码 请指导-asp.net 与程序结合php发布以后为什么出现乱码?

问题描述 asp.net 与程序结合php发布以后为什么出现乱码? php开发的程序,其中有一些asp.net代码,现在已经发布 网址:http://www.51zhanpianyi.com 但是在一些模块会出现乱码,请指导. 解决方案 没发现有什么问题啊:

IIS处理Asp.net请求和Asp.net页面生命周期详细说明_实用技巧

ASP.NET 页运行时,此页将经历一个生命周期,在生命周期中将执行一系列处理步骤.这些步骤包括初始化.实例化控件.还原和维护状态.运行事件处理程序代码以及进行呈现.了解页生命周期非常重要,因为这样做您就能在生命周期的合适阶段编写代码,以达到预期效果.此外,如果您要开发自定义控件,就必须熟悉页生命周期,以便正确进行控件初始化,使用视图状态数据填充控件属性以及运行任何控件行为代码.(控件的生命周期基于页的生命周期,但是页引发的控件事件比单独的 ASP.NET 页中可用的事件多.)       一般

IIS处理Asp.net请求和Asp.net页面生命周期说明

首先我们要弄清楚两个非常重要的概念: 1, worker process(w3wp.exe). worker process管理所有的来自客户端的请求并给出响应.它是IIS下asp.net应用程序的核心. 2, application pool. 它是worker process的容器,IIS5及之前的IIS版本均没有application pool的概念.每一个application pool对应着一个worker process,在IIS Metabase中维护着Application Po

Win32编程中请慎用ebx/esi/edi

根据我的试验,在win2000以上操作系统对于ebx,esi,edi好像是拿来就用,没有进行保护和恢复,如果你的程序中使用了这几个寄存器,请一定先压栈,用完后恢复.否则会使程序在win98下正常,在win2000下出现莫名其妙的非法操作,一般是提示某个地址不能进行读写操作,而这个地址并不在你的程序的控制下.

请慎用java的File#renameTo(File)方法(转)

  以前我一直以为File#renameTo(File)方法与OS下面的 move/mv 命令是相同的,可以达到改名.移动文件的目的.不过后来经常发现问题:File#renameTo(File)方法会返回失败(false),文件没有移动,又查不出原因,再后来干脆弃用该方法,自己实现一个copy方法,问题倒是再也没有出现过.  昨天老板同学又遇到这个问题,File#renameTo(File)方法在windows下面工作的好好的,在linux下偶尔又失灵了.回到家我扫了一遍JDK中File#ren

请慎用邮件营销 你的邮件是如何“逼”走用户的

中介交易 SEO诊断 淘宝客 云主机 技术大厅 译者注:营销邮件对我们来说都不陌生,也许大家的邮箱里现在还躺着很多QQ团购.易迅.大众点评等邮件,也许很多时候你根本都不会打开来看一眼,也许你也头疼要怎么处理这些邮件--此文从众多角度提炼用户的心声,观点精辟,尤其值得电商童鞋借鉴和学习. 原文地址:http://www.smashingmagazine.com/2013/02/11/how-email-alienate-users/ 垃圾邮件!也许只有Monty Python会喜欢,我们就没那么确

IIS处理Asp.net请求和Asp.net页面生命周期说明_实用技巧

首先我们要弄清楚两个非常重要的概念: 1, worker process(w3wp.exe). worker process管理所有的来自客户端的请求并给出响应.它是IIS下asp.net应用程序的核心. 2, application pool. 它是worker process的容器,IIS5及之前的IIS版本均没有application pool的概念.每一个application pool对应着一个worker process,在IIS Metabase中维护着Application Po