使用 Dojo 构建安全的混搭应用

了解使用 Dojo 框架构建安全混搭的高级概念和实现细节。理解混搭技术安全威胁的来源,以及使用 Dojo 开发混搭时克服安全威胁的技术。

Jeffrey J. Hanson, CTO, Max International

http://www.ibm.com/developerworks/i/p-jhanson.jpgJeff Hanson 拥有 20 多年的软件工程师和架构师经验,目前是 Max International 的 CTO。Jeff 撰写了许多文章和图书,包括 Mashups: Strategies for the Modern Enterprise



2011 年 6 月 02 日

术语混搭(mashup) 通常用于描述通过将两首或多首现有歌曲混合在一起来谱写一首新歌的技术。对于 web 应用程序,混搭 描述合并现有 UI 工件、流程、服务和数据来创建新 web 页面、应用程序等的方法。许多用户和社会媒体环境都使用这种技术。

Mashups 支持通过使用可回收的 UI 元素和松散耦合的服务快速开发新 web 页面和应用程序。它们创建一个敏捷、动态的开发环境,允许技术技巧有限的用户开发强大、有用的 web 页面和应用程序。大多数混搭通过合并现有 UI 工件和高级标记和脚本语言(比如 HTML 和 JavaScript 代码)实现。

混搭开发面临的威胁

混搭开发模型引入了一个开放环境,这个开放环境带来了新的安全威胁,使安全成为开发人员考虑的一个主要问题。由于混搭页面可用于未来混搭的工件或数据源,因此不可能准确预测这些元素将在后续部署中如何使用。因此,关键是开发人员在整个开发生命周期中解决安全问题。

您必须采取新措施来应对混搭开发模型中不断增长的安全风险;传统安全措施,比如 DMZs 和防火墙,不能处理混搭 UI 工件和数据需要的细粒度访问。除了处理传统威胁外,混搭应用程序或 web 页面必须解决跨站点脚本编写(XSS)和跨站点请求伪造(CSRF)等问题。

跨站点脚本编写

狡猾的黑客能够利用软弱的会话管理。例如,当用户被重定向到一个登录页面时,服务器已经对一个现有用户开放,即使 新用户正在向它提供凭证。服务器相信会话已处于活动状态,从而返回一个确信响应给新用户,这表明一个全新的会话被创建且凭证已被安全存储。现有会话的秘密所有者 — 那个黑客 — 此时能够记录和利用在新用户和服务器之间传输的数据,前提是会话保持活动。XSS 技术经常被攻击者采用来绕过浏览器的防火墙,将数据重定向一个第三方站点进行记录。

跨站点请求伪造

在一个 CSRF 攻击过程中,请求源自一个入侵的第三方站点并通过一个已验证的浏览器页面传递到服务器。然后响应被返回到入侵者站点。通常安全机制认为,一旦一个已验证会话已被建立,那么来自已验证的浏览器的所有后续请求都是都是有效的。因此,如果入侵站点能够使已验证浏览器在它和服务器之间来回传递请求和响应,那么该站点就和已验证浏览器拥有同样的特权,隐私就会被侵害。浏览器的同源策略无法阻止 CSRF 攻击,因为攻击请求被传输到第三方入侵站点的代理中相同的源。


了解 Dojo

Dojo Toolkit(参见 参考资料 了解更多信息)是一个开源应用程序编程接口(API)、皮肤和小部件 JavaScript 框架,用于使用 JavaScript 代码、HTML、CSS 和 Ajax 构建应用程序和网站。它包含图表、动画、层级树、日历、菜单和其他元素。对于跨浏览器 Ajax 开发,Dojo 在 XMLHttpRequest (XHR) 对象之上提供了一个抽象层。

Dojo 是围绕一个层级包装系统构建的,该系统支持使用名称空间的模块式开发。这允许第三方库和应用程序扩展 Dojo 功能而不必覆盖对象和功能名称。Dojo 包包含一个或多个文件,在其他文件上有可选的依赖项。

Dojo 还提供一个机制来构建配置文件(profile)— 合并在一起进行统一加载、初始化和缓存的一组包。使用配置文件,Apache Ant 这样的系统能够创建一个包含给定配置文件中指定的包和依赖项的压缩 JavaScript 文件。一些常见用例含有一些预构建配置文件可用。

通过 Dojo 保护 CSRF

您通常可以通过要求每个请求在发送时传递一个惟一的令牌或 cookie 来阻止 CSRF 攻击,这可以通过 Dojo 来完成。由于所有 XHR 请求都通过 dojo.xhr() 调用来路由,您可以覆盖这个调用以包含一个用作惟一令牌的额外头部,如 清单 1 所示。

清单 1. 包含一个额外头部来覆盖 XHR 请求
var originalXHR = dojo.xhr;
dojo.xhr = function(httpVerb, xhrArgs, hasHTTPBody)
{
  // Use the session ID (JSESSIONID for Java, PHPSESSID for PHP)
  // as the token value
  args.headers["Request-Token"] = dojo.cookie("JSESSIONID");
  return originalXHR(httpVerb, xhrArgs, hasHTTPBody);
}

这段代码就绪后,服务器将检查每个请求,验证 Request-Token 头部存在并拥有与会话 ID 相同的值。服务器将假设 Request-Token 头部中缺乏正确的值的任何请求都是 CSRF 攻击企图并将拒绝它们。


DojoX Secure

DojoX 是 Dojo Toolkit 的一个扩展框架,用作一个代码存储库,一个试验代码孵化器、以及其他 Toolkit 扩展的一个测试环境。

DojoX Secure 是 DojoX 框架的一组工具和子项目,旨在解决处理潜在恶意的数据和代码时产生的安全问题。DojoX Secure 提供三个主包:

  • dojox.secure.sandbox 包提供一些特性和工具,以使用 XHR 对象从外部域加载 JSON 数据、web 页面和脚本。它为浏览器的 DOM 提供一个沙箱环境来阻止其恶意操纵。
  • dojox.secure.capability 包确保一个脚本之前的 JavaScript 验证能够访问或修改沙箱环境之外的 JavaScript 对象。
  • dojox.secure.DOM 包限制对浏览器的 DOM 的指定分支的访问。

Dojo XHR 插件注册表

Dojo 1.2 版提供了一个新的 XHR 插件注册表,允许您使用不同的传输机制来处理一个给定浏览器和服务器的特性和功能。插件注册表旨在跨域规范和协议可用时支持它们。使用这个注册表,您可以指定不同的传输机制,同时保持脚本编写代码的其余部分完整,这使资源传输脚本和资源操作脚本分离。

DojoX Secure 包含从外部域安全加载潜在恶意的代码、内容和 UI 工件需要的组件。它还确保脚本可以安全执行,并提供一个沙箱来控制 DOM 的访问和修改。这些特性使得 DojoX Secure 成为保护混搭构造的一个宝贵的贡献者。

下面的小节介绍如何使用 dojox.secure 包来阻止特定的混搭安全威胁。

加载跨域资源

DojoX Secure 依赖 DojoX XHR 插件注册表框架来从跨域站点获取资源。这个传输框架支持帮助访问这些资源的新兴技术(比如用于 Windows® Internet Explorer® version 8 的 XDomainRequest 对象和 W3C 的 Cross-Origin Resource Sharing specification)。在浏览器基于这些新兴技术的标准化之前,仍需要一个替代方案;DojoX 提供两个马上可用于访问跨域资源的传输插件:

  • 代理服务器传输插件依赖原始域上的一个代理服务器服务。这样一个服务运行时,可以从一个外域请求资源,这个外域指定为 xhrPlugins 对象的 addProxy 函数的一个参数。例如,下面的代码段演示将一个请求发送到一个代理服务器服务,以连接到 example.com 并检索一个名为 someresource 的资源:

    dojox.io.xhrPlugins.addProxy("/proxy?url=http://example.com/someresource");
  • window.name 传输插件可用于支持 window.name 协议的 web 页面或应用程序。这个协议创建一个 iframe,然后将该 iframe 的名称设置为将被检索的数据,比如 myiframe.contentWindow.name = "This is some data."。主 HTML 文件然后获取 myiframe.contentWindow.name 值。要定义应该通过 window.name 协议从 example.com 加载的资源,按如下方式注册 example.com 站点:

    dojox.io.xhrWindowNamePlugin("http://example.com");

当您定义检索资源的传输机制后,创建一个沙箱将资源加载到其中。

在沙箱中操作

使用 DojoX Secure 来创建一个沙箱需要两个步骤:

  1. 定义一个 DOM 元素,将其用作沙箱。这个元素可以是一个简单的标准 <div> 声明:
    <div id="mySandbox"></div>
  2. 创建一个沙箱。这个步骤通过一个单行 DojoX 函数调用(<div> ID 作为一个参数传递)完成:
    var mySandbox = dojox.secure.sandbox(dojo.byId("mySandbox"));

现在沙箱已经创建,使用 loadHTML 函数将该沙箱加载到沙箱中:

mySandbox.loadHTML("http://example.com/snippet.html");

loadHTML 函数从一个给定 URL 加载一个 HTML 代码段,并将其注入沙箱 DOM 元素中。如果该代码段包含脚本代码,则脚本也被沙箱化。

您还可以使用 loadJS 函数调用加载 JavaScript 文件并在沙箱中执行它们:

var result = mySandbox.loadJS("http://example.com/snippet.js");

loadJS 函数加载指定 JavaScript 文件的内容。JavaScript 代码首先被验证,以确保其安全,然后在沙箱的范围内执行;沙箱将已加载和已执行的代码限制到沙箱 DOM 元素及其任意子节点。dojox.secure 沙箱机制如 图 1 所示。

图 1. DojoX Secure 沙箱
DojoX Secure 沙箱为 JavaScript 代码的安全执行提供一个位置

沙箱内创建的任意有效值或对象,比如 loadJS 调用的结果,允许主文档的 JavaScript 环境访问。

为提供一个安全的环境,有些标准 JavaScript 功能(比如,使用 eval()、限制对全局变量的访问、使用 [] 操作符、以及声明一个 <link> 标记)在 DojoX Secure 沙箱环境中变得不可用或受到限制。

除了加载沙箱资源外,DojoX Secure 提供可用于构建沙箱 UI 工件的功能。

创建安全的 UI 工件

由于 DojoX Secure 沙箱脚本能够访问沙箱元素,您可以直接在沙箱元素上执行 DOM 元素创建和操作。通过将 DOM 操作限制到沙箱元素的子元素和节点,您可以在沙箱中安全地操作浏览器的 DOM。

清单 2 展示了可以在 DojoX Secure 沙箱中创建的一个简单 UI 工件。

清单 2. 一个沙箱 UI 工件
<div id="mySandbox">
  <script type="text/javascript">
    var widget = document.createElement('div');
    widget.setAttribute('id', 'testwidget');
  
    widget.style.width = 300;
    widget.style.height = 300;
    widget.style.background = "#0f0";
    widget.style.border = "4px solid #000";
  
    widget.innerHTML = "This is some data for the widget.";
    document.getElementById("mySandbox").appendChild(widget);
  </script>
</div>

清单 2 中展示的功能演示了在原始域中动态创建和加载的一个 UI 工件。但是,从其他域创建和加载 UI 工件同样轻松。这个代码允许您编写一些 UI 工件以便在任何 DojoX Secure 沙箱中使用,并实现安全加载和执行。


结束语

混搭允许您使用高级脚本语言,通过回收和重用现有工件来创建新的 UI。混搭还帮助您使用不需要复杂编程和中间件技术的语义丰富的数据格式来快速轻松地集成完全不同的数据。

混搭引入了一个开放的开发模型,在开发一个混搭应用程序时,这个开发模型的弱点使安全问题浮出水面。由于混搭页面还可用作后续混搭的来源,因此不可能准确预测混搭工件、页面和数据源将来将如何使用。由于每个混搭对于后续混搭的潜在作用,因此必须在整个流程中解决安全问题。

DojoX Secure JavaScript 框架提高了您构建安全混搭的能力。它的 APIs、工具和子项目允许您在一个沙箱环境中加载资源并执行脚本。DojoX Secure 还在上述环境中提供与浏览器的 DOM 的交互,从而加强了 UI 工件的安全开发和部署。

这些概念和细节是一个正在进行的谈话的一部分,这个谈话旨在讨论通过使用 dojox.secure 框架来进行开发,从而减小混搭安全威胁的一些技术。

参考资料

学习

获得产品和技术

讨论

条评论

developerWorks: 登录

标有星(*)号的字段是必填字段。


需要一个 IBM ID?
忘记 IBM ID?


忘记密码?
更改您的密码

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件

 


在您首次登录 developerWorks 时,会为您创建一份个人概要。您的个人概要中的信息(您的姓名、国家/地区,以及公司名称)是公开显示的,而且会随着您发布的任何内容一起显示,除非您选择隐藏您的公司名称。您可以随时更新您的 IBM 帐户。

所有提交的信息确保安全。

选择您的昵称



当您初次登录到 developerWorks 时,将会为您创建一份概要信息,您需要指定一个昵称。您的昵称将和您在 developerWorks 发布的内容显示在一起。

昵称长度在 3 至 31 个字符之间。 您的昵称在 developerWorks 社区中必须是唯一的,并且出于隐私保护的原因,不能是您的电子邮件地址。

标有星(*)号的字段是必填字段。

(昵称长度在 3 至 31 个字符之间)

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件.

 


所有提交的信息确保安全。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=Web development
ArticleID=676751
ArticleTitle=使用 Dojo 构建安全的混搭应用
publish-date=06022011