如何使用HTML5 Sandbox保护您的网站





5.00/5 (3投票s)
HTML5 Sandbox
当今的 Web 应用程序将各种新体验整合到一个统一的体验中。例如,显示关于某产品的最新推文的 Twitter 小部件。或者讨论文章的 Facebook 评论。甚至只是通过 IFRAME 元素集成的网页。这些体验可能会增加您网站的安全漏洞。
不要担心……有一个新工具可以帮助您:HTML5 Sandbox。 但在我开始介绍它之前,让我们快速回顾一下 IFRAME 元素的问题。
一个黑盒子
嵌入 IFRAME 内容就像在 Facebook 上公开宣布派对。您认为您知道邀请了谁,但实际上您不知道是谁转发的,也不知道谁会来。
嵌入内容也是如此。您知道您在引用什么,但您不知道该网站将来会如何发展。内容或功能(或两者)随时可能发生变化。在您不知情的情况下……也未经您的批准。
使用 iframe 的安全隐患
浏览器像处理其他任何网页一样处理使用 IFRAME 的页面。表单可用于检索用户输入,脚本可被执行,页面可在浏览器窗口内导航,浏览器插件也可被执行。就像失控的派对捣乱者一样,您无法控制托管内容将执行什么操作。
默认情况下,有一个机制可以阻止某些类型的攻击:跨域策略。
重新托管来自其他域的内容
如果托管内容来自其他域,则会启用跨域策略,它会阻止“外部”内容访问父文档对象模型。
因此,嵌入式页面无法读取托管域的 cookie 或浏览器本地存储。但仍然存在风险。
托管内容仍然可以重新导航到顶级窗口。通过显示用户期望的内容,该网站可能会尝试从用户那里钓取机密信息。或者,通过使用风格相似的表单,尝试恶意捕获用户信息。
因此,即使启用了跨域策略,仍然存在巨大的安全风险。
重新托管来自同一域的内容
从同一域重新托管内容的情况就更糟糕了。
当内容来自同一域时,不存在默认的安全限制。嵌入式内容可以访问已加载的完整浏览器 DOM 并操纵一切。
同一域的内容应该是安全的,这似乎是有道理的。这里的风险主要来自于在 IFRAME 中重新托管的用户生成内容。
沙箱化方法
这些有效的安全问题在很长一段时间内都没有得到标准机构的妥善解决。在没有明确的 W3C 标准的情况下,必须以某种方式保护主机免受框架内容的影响。例如,Microsoft 在 Internet Explorer 8 中提供了 IFRAME 安全性的专有实现。其他人也采用了它,并将其讨论为他们浏览器的一个基准。但自 IE8 以来,标准已大大成熟。
包括 Chrome、Firefox 和 IE10 Platform Preview 在内的现代浏览器都基于 W3C IFRAME Sandbox 属性。
今天我们将使用 Sandbox 构建这些。请在此处查看演示。
让我们开始应用沙箱。只需将其作为空属性添加到 IFRAME 元素中。
<iframe sandbox src="http://somewebsite.com/default.html"></iframe>
就是这样!
现在,IFRAME 沙箱化内容将在浏览器中重新托管,并带有以下限制:
- 禁用插件。 任何 ActiveX、Flash 或 Silverlight 插件都不会被执行。
- 禁用表单。 托管内容不允许将表单发布到任何目标。
- 禁用脚本。 JavaScript 被禁用,不会被执行。
- 禁用指向其他浏览上下文的链接。 指向不同浏览器级别的锚标签将不会被执行。
- 唯一来源处理。 所有内容都将作为唯一来源进行处理。内容无法遍历 DOM 或读取 cookie 信息。
这意味着,即使是来自同一域的内容,也将被视为唯一来源,因为每个 IFRAME 内容都将被视为一个唯一来源。
嵌入式内容仅允许显示信息。 IFRAME 内部不允许执行任何其他可能危及托管网站或利用用户信任的操作。
检查 Sandbox 属性
我们知道 IFRAME 是一个敞开的大门。我们知道 sandbox 属性可以锁定托管内容的安全性。决定很明确:仅使用带有 sandbox 属性的 IFRAME 元素!
您可以使用简单的 JavaScript 检查来确认浏览器是否支持 IFRAME sandbox 属性。
if( "sandbox" in document.createElement( "IFRAME" ) ) {
// render the iframe element...
} else {
// embed content through other ways,
// as the browser does not support the sandbox
}
如果支持,则使用 sandbox 属性。如果不支持,请尝试通过其他方式嵌入内容,或提示用户升级到现代浏览器。
自定义 Sandbox
在某些情况下,您可能需要对限制进行一定程度的自定义,这完全是可能的。
几个属性值可以放宽标准的沙箱策略。
allow-forms
如果您想在 IFRAME 元素内启用表单回发,只需为 sandbox 属性指定 allow-forms 值。
<iframe sandbox="allow-forms" src="xyz.html"></iframe>
如果存在此值,则嵌入式页面允许在框架内使用表单提交进行回发。
allow-scripts
JavaScript 是一种功能强大的语言,通常用于在客户端实现动态交互,而无需将信息发送回服务器。但当重新托管外部网页时,这种强大的功能也带来了风险。因此,您应仔细考虑是否真的要在 IFRAME 场景中启用 JavaScript——尤其是在内容来自未知来源时。
通过 allow-scripts 值可以启用 JavaScript。
<iframe sandbox="allow-scripts" src="xyz.html"></iframe>
allow-same-origin
默认情况下,来自同一域的 IFRAME 页面可以访问父文档对象模型。
在 sandbox 属性到位的情况下,该页面将被视为不来自同一来源。即使来自同一域,此页面也无法访问资源。
要在沙箱化场景中重新启用同源处理,您必须指定 allow-same-origin 属性。
<iframe sandbox="allow-same-origin" src="xyz.html"></iframe>
该值本身不是很有用,因为您需要一些脚本功能才能使用它。
例如,如果您想像这样访问当前域的本地存储
function loadFromStorage( key ) {
if( localStorage ) {
return localStorage.getItem( key );
}
});
……您还需要 allow-scripts 值。
<iframe sandbox="allow-scripts allow-same-origin" src="xyz.html"></iframe>
现在访问成功了!
但请注意:允许同一沙箱中存在多个脚本可能会导致安全漏洞。例如,您托管的内容可能会操纵沙箱的属性并移除进一步的限制。
allow-top-navigation
当您使用 sandbox 属性时,指向其他浏览上下文的锚点默认会被忽略且不执行。这可以防止托管 IFRAME 内容的网站被托管内容替换。
例如,此链接在默认沙箱中不会被执行,因为目标会替换整个网页。
<a href="xyz.html" target="_top">Click me</a>
仅当您信任您托管的内容时,才建议放宽此策略。
<iframe sandbox="allow-top-navigation" src="xyz.html"></iframe>
ms-allow-popups
有时允许嵌入式内容打开新弹出窗口很有用。一个完美的例子是地图服务,如 Bing Maps。
嵌入 Bing Maps 时,可以在弹出窗口中查找其他功能,如驾车路线或目的地详细信息。但由于沙箱禁止此操作,Internet Explorer 10 中有一个设置可以在不影响沙箱的情况下启用弹出窗口。
以下代码显示了如何设置 ms-allow-popups。
<iframe sandbox="ms-allow-popups" src="xyz.html"></iframe>
设置此值后,嵌入式网站可以在新窗口中显示信息。
<a href="xyz.html" target="_new">Show Info</a>
整合
您可以在一个沙箱中组合多个属性值。例如,如果您想启用表单回发、顶级导航和 JavaScript,只需指定:
<iframe sandbox="allow-forms allow-top-navigation allow-scripts" src="xyz.html"></iframe>
另外,值得一提的是,当用于分层情况时,沙箱也能正确运行,即使用具有不同 sandbox 属性值的多个嵌套 IFRAME。顶级沙箱始终支配其下层。
动手实践!
您可以在此演示中试用 HTML Sandbox。您也可以从 Github下载此演示的副本。要启用表单回发演示,只需在 WebMatrix 中打开项目文件夹并从中启动项目。
然后,下载一个现代浏览器(例如Internet Explorer 10 Platform Preview),并通过阅读IE 开发人员指南来熟悉 sandbox。这个单独的属性是实现更安全 Web 的一大进步……而现代浏览器终于准备好对嵌入式内容进行沙箱化处理了。