同时沙盒并将 JS/HTML 添加到 iFrame

Bry*_*yce 5 html javascript security iframe sandbox

我正在尝试创建一个内部有 JS 火的 iframe,但无法访问父文档。目标是有一个简单的实现并且不包含任何特殊的库。我发现HTML5 Sandbox属性是一个可行的解决方案;然而,事实证明,同时沙箱 iframe并将JS 放入其中是相当困难的。

我努力了:

  1. 将 JS 添加到 iframe,然后将其从父文档中沙箱化。这不起作用,因为 iframe 中的 JS 在应用 iframe 沙箱之前触发
  2. 创建 iframe 并使用srcdoc属性设置 HTML(例如<iframe sandbox="allow-scripts" srcdoc="<body><script src='sample1.js'></script><script src='sample2.js'></script></body>"></iframe>),根据此处,这在 IE 中不起作用
  3. 创建 iframe 并使用src属性设置 HTML(例如<iframe sandbox="allow-scripts" src="javascript:&quot;<html><body><script src='sample1.js'></script><script src='sample2.js'></script></body></html>&quot;"></iframe这在 Firefox 38.0.5 (Mac OS X Yosemite) 中不起作用,但在 Chrome 43 和 Safari 8.0.4 中起作用......“在 Firefox 中不起作用”意味着它确实会允许sample2.js添加<span></span>到iframe DOM,但它不设置span的innerText;因此,它不能按预期工作。
  4. 最后,我刚刚尝试通过JS动态创建一个iframe。将 iframe 添加到 DOM(没有沙箱属性)后,我向其中写入 HTML,其中包含我想要在 iframe 中沙箱化的脚本。在 iframe 头部,我有一个沙箱脚本。不幸的是,这似乎不起作用。(代码如下)

我创建了一个JSFiddle,但它没有给出正确的行为,因为它位于嵌套的 iframe 中...我设置了一个简单的页面并正在我的本地主机上进行测试。这是我用于测试的代码:

<html>
<head>
<meta content="text/html;charset=utf-8" http-equiv="Content-Type">
<meta content="utf-8" http-equiv="encoding">
</head>
<body>

<!-- Case #2 ~ Does not work in IE -->
<iframe srcdoc="<body><script src='sample1.js'></script><script src='sample2.js'></script></body>" sandbox="allow-scripts">
</iframe>

<!-- Case #3 ~ Does not work in Firefox -->
<iframe src="javascript:&quot;<html><body><script src='sample1.js'></script><script src='sample2.js'></script></body></html>&quot;" sandbox="allow-scripts">
</iframe>

<!-- Case #4 ~ Sandbox maybe not applied? -->
<script>
var i   = document.createElement('iframe');
i.src   = "about:blank";
i.id    = "bryce_iframe";
document.body.appendChild(i);
// iframe added to page

var j = document.getElementById('bryce_iframe').contentDocument;
j.open();

var js = "<html><head>" +
         "<scr"+"ipt>window.top.document.getElementById('bryce_iframe').sandbox = 'allow-scripts';</scr"+"ipt>" +
         "</head><body>" +
         "<p>Hi</p>" +
         "<scr"+"ipt>" +
         "var p = document.createElement('p');" + 
         "p.innerText = 'should throw error'; console.log(p);" +
         "window.top.document.body.appendChild(p);" +
         "</scr"+"ipt>" +
         "</body></html>";
// "window.top.document.body.appendChild(p)" should throw an error because of sandbox

j.write(js);

j.close();
</script>

</body>
</html>
Run Code Online (Sandbox Code Playgroud)

我的sample1.js 文件如下所示:

var s = document.createElement('span');
s.innerText = "hi";
window.top.document.body.appendChild(s);
Run Code Online (Sandbox Code Playgroud)

我的sample2.js 文件如下所示:

var txt = "this doesn't try to break out of iframe";
var s = document.createElement('span');
s.innerText = txt;
document.onload=document.body.appendChild(s);
Run Code Online (Sandbox Code Playgroud)

几周来我一直在寻找有关此问题的有用资源。如果有另一双眼睛和我一起研究它,那就太棒了。

我期待与任何伸出援手的人合作。先感谢您。

Sil*_*Fox 0

只是想知道为什么要sandbox在示例 #4 中的内部脚本中添加该属性?:

"<scr"+"ipt>window.top.document.getElementById('bryce_iframe').sandbox = 'allow-scripts';</scr"+"ipt>" +
Run Code Online (Sandbox Code Playgroud)

沙箱属性应添加到父代码中:

<!-- Case #4 ~ Sandbox maybe not applied? -->
<script>
var i   = document.createElement('iframe');
i.src   = "about:blank";
i.id    = "bryce_iframe";
i['sandbox'] = 'allow-scripts';
document.body.appendChild(i);
Run Code Online (Sandbox Code Playgroud)

这将阻止家长访问。