使用iframe进行沙盒处理?

时间:2011-06-16 03:17:09

标签: javascript iframe

我正在开发一个允许在小部件中使用用户编写的javascript的系统。为了确保安全,我计划在iframe中对这些小部件进行沙盒处理。当然,为了使沙箱有效,iframe必须具有与父文档不同的域。

我真的很想能够使用与此类似的代码动态生成iframe:

template = '<html><body><script>/* user code */</script></body></html>'
src      = 'javascript: document.write("' + template + '")'
widget   = $('<iframe>').attr('src', src)

$('#container').append(widget)

...然后将生成的iframe视为父窗口的跨域。这是可能的,如果是这样,它将如何完成?

1 个答案:

答案 0 :(得分:3)

好吧,我想我得到了你需要的但是有点棘手。 您想创建一个<iframe>并使用用户Javascript客户端填充它,但仍然将客户端沙箱化?

这是相当不标准的。通常,<iframe>的内容是生成服务器端的。但是它就在这里。

首先是一些背景:文档无法访问不是来自同一域(包括子域)和端口的任何文档的内容。但是他们可以使用document.domain属性更改自己的安全域。所以你需要做的就是减轻安全性,然后再将其重新收紧,以便用户脚本运行。

因此,您无法按照指定的方式执行此操作,因为如果您使用Javascript <iframe>创建src,则document.domain将与父框架匹配。这意味着窗口小部件可以完全访问所有内容。

所以这就是你如何做到的:

  1. 设置主域的两个子域。我们称他们为home.example.comwidgets.example.com
  2. widgets.example.com上创建一个基本的HTML文件,并确保它调用此javascript:document.domain = "example.com";
  3. 现在创建包含所有这些小部件的页面。将其document.domain设置为相同的值。
  4. 创建所有iframe,将基本HTML页面从widgets.example.com加载到其中。
  5. 在包含用户模板的框架内设置变量。例如:myFrame.contentWindow.foo = "template";
  6. 将主窗口上的document.domain切换回home.example.com,以便<iframe>无法再访问父框架
  7. 在框架中触发模板替换
  8. 最后一部分是棘手的部分。您不能只嵌入代码,因为如果它自动运行,它将在您更改主文档的域之前运行,这将是一个安全问题。因此,您需要将其设置为框架内的临时变量,然后以某种方式触发框架以使用该模板替换其自己的内容,但仅在锁定所有内容之后。最简单和最兼容的方法是在调整大小时触发它,然后只改变框架的宽度或高度。

    现在,或者,如果小部件填充在服务器端:

    1. widgets.example.com
    2. 上的主机小部件
    3. 包含home.example.com
    4. 小部件的主机页面
    5. 完成
    6. 但我认为你有理由在客户端做到这一点。

      逻辑上的下一个主题:帧之间的通信和自动调整大小。但那些是另一天。

      我是否回答了你的问题?我希望如此,因为这是很多打字,如果你投票并接受我的回答,我不会介意声望点! ;)