ASP.Net 1.1后引入了对提交表单自动检查是否存在XSS(跨站脚本攻击)的能力。当用户试图用<xxxx>之类的输入影响页面返回结果的时候,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 异常,而且可以按照程序员的意愿返回一个合理的报错信息。

这段代码很简单,所以我希望所有不是真的要允许用户输入<xxx>之类字符的朋友,千万不要随意的禁止这个安全特性,如果只是需要异常处理,那么请用类似于上面的代码来处理即可。

而对于那些通过 明确禁止了这个特性的程序员,自己一定要明白自己在做什么,而且一定要自己手动的检查必须过滤的字符串,否则你的站点很容易引发跨站脚本攻击。

关于存在Rich Text Editor的页面应该如何处理?

如果页面有富文本编辑器的控件的,那么必然会导致有<xxx>类的HTML标签提交回来。在这种情况下,我们不得不将validateRequest="false"。那么安全性怎么处理?如何在这种情况下最大限度的预防跨站脚本攻击呢?

根据微软的建议,我们应该采取安全上称为“默认禁止,显式允许”的策略。

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

然后,我们再对我们所感兴趣的、并且是安全标签,通过Replace()进行替换。比如,我们希望有"<b>"标签,那么我们就将"&lt;b&gt;"显式的替换回"<b>"。

示例代码如下:

  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;", "");
    sb.Replace("&lt;i&gt;", "<i>");
    sb.Replace("&lt;/i&gt;", "");
    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>

ASP.NET脚本过滤-防止跨站脚本攻击[转]的更多相关文章

  1. ASP.NET脚本过滤-防止跨站脚本攻击(收集别人的)

    ASP.Net 1.1后引入了对提交表单自动检查是否存在XSS(跨站脚本攻击)的能力.当用户试图用<xxxx>之类的输入影响页面返回结果的时候,ASP.Net的引擎会引发一个 HttpRe ...

  2. JAVA覆写Request过滤XSS跨站脚本攻击

    注:本文非本人原著. demo的地址:链接:http://pan.baidu.com/s/1miEmHMo 密码:k5ca 如何过滤Xss跨站脚本攻击,我想,Xss跨站脚本攻击令人为之头疼.为什么呢. ...

  3. Web攻防系列教程之跨站脚本攻击和防范技巧详解

    摘要:XSS跨站脚本攻击一直都被认为是客户端Web安全中最主流的攻击方式.因为Web环境的复杂性以及XSS跨站脚本攻击的多变性,使得该类型攻击很 难彻底解决.那么,XSS跨站脚本攻击具体攻击行为是什么 ...

  4. PHP进行安全字段和防止XSS跨站脚本攻击过滤(通用版)

    废话不多说,直接贴使用方法和代码: 使用方式:1)写在公共方法里面,随时调用即可.2)写入类文件,使用是include_once 即可 代码: /* 进行安全字段和xss跨站脚本攻击过滤(通用版) - ...

  5. XSS(跨站脚本攻击)的最全总结

    从OWASP的官网意译过来,加上自己的理解,算是比较全面的介绍.有兴趣的可私下交流. XSS 跨站脚本攻击 ============================================== ...

  6. Web安全测试之XSS(跨站脚本攻击)

    XSS 全称(Cross Site Scripting) 跨站脚本攻击, 是Web程序中最常见的漏洞.指攻击者在网页中嵌入客户端脚本(例如JavaScript), 当用户浏览此网页时,脚本就会在用户的 ...

  7. 教你ASP.NET中如何防止注入攻击

    你应该在程序中验证所有的不信任输入.你应该假定所有的用户输入都是非法的.用户可以在应用程序中提供表单字段,查询字串,客户端cookies和浏览器环境值比如用户代理字串和IP地址等. 弱输入校验通常为注 ...

  8. 【安全测试】Web应用安全之XSS跨站脚本攻击漏洞

    前言 以前都只是在各类文档中见到过XSS,也进行过相关的学习,但是都是一知半解,过了一段时间就忘了. 前几天我们收到了了一份标题为<XX账号昵称参数中存在存储XSS漏洞>的报告文档,来源是 ...

  9. web应用程序安全攻防---sql注入和xss跨站脚本攻击

    kali视频学习请看 http://www.cnblogs.com/lidong20179210/p/8909569.html 博文主要内容包括两种常见的web攻击 sql注入 XSS跨站脚本攻击 代 ...

随机推荐

  1. 动画——animation部分

    动画部分是HTML5的新增部分,其特性是可以不借助js代码就可以单单凭借着css部分完成部分动态效果.其效果华丽,强大,炫酷无比,只要你想得到的动态效果都可以通过css3来完成. <style& ...

  2. android activity四种启动模式

    1.standard <activity android:name=".MainActivity" android:launchMode="standard&quo ...

  3. Unity中www的基本应用

    Unity的www主要支持HTTP中的GET和POST方式,GET方式会将请求附加到URL后,POST方式则是通过FORM的形式提交. 以下为Unity客户端的信息: using UnityEngin ...

  4. PAT1015

    A reversible prime in any number system is a prime whose "reverse" in that number system i ...

  5. HTTP 中 POST和GET的区别

    1.传送数据的方式不一样 get是将数据队列添加到URL中提交,用户可以看到(对URL反编码就行) post是将数据队列放到HTTP的报文的报头中提交,用户看不到所提交的数据: 2.服务器端获取变量的 ...

  6. 我也谈javascript闭包的原理理解

    参考原文:http://www.oschina.net/question/28_41112 前言:还是一篇入门文章.Javascript中有几个非常重要的语言特性——对象.原型继承.闭包.其中闭包 对 ...

  7. 2016沈阳网络赛 odd-even number

    odd-even number Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) ...

  8. CentOS 6.5添加163源

    1.首先备份/etc/yum.repos.d/CentOS-Base.repo mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS ...

  9. Android开源项目收集

    软件名:gaeproxy软件作用:Android手机配置GoAgentFQ.项目地址:https://github.com/madeye/gaeproxy.git 软件名:ProxyDroid软件作用 ...

  10. PAT (Advanced Level) 1047. Student List for Course (25)

    简单题. #include<iostream> #include<cstring> #include<cmath> #include<algorithm> ...