商讯信箱
用户名: @
密  码:   注册|忘记密码
登录
个人用户经销商
信箱 E杂志
您的位置:首页 > 技术频道 > 正文

征服 Ajax 应用程序的安全威胁

—— 学习一些技巧和最佳实践,使您的 mashup 应用程序安全无虞

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

同源策略是当前浏览器的保护机制的一部分,该机制将来自不同域(假设域代表的是始发者)的 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中,所传递的是 usernamereservation 作为名称值对传递。此外,查询字符串还包含向服务器请求的输出格式和回调函数的名称(即 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 的集合之间的关联时才会要求用户配置。然而,不难想象一些用户可能会被欺骗,在没有完全理解其后果时就接受该安装。

1 2 3 4 5 6 7
【内容导航】
第1页: 前言 第2页: 理解同源策略
第3页: 研究攻击场景 第4页: 理解攻击产生的影响
第5页: 推荐的最佳实践 第6页: 结束语
第7页: 作者介绍
©版权所有。未经许可,不得转载。
[责任编辑:郑重]