在客户端的 IFRAME 中对内容进行沙盒处理

Sandboxing content in an IFRAME, on the client side

本文关键字:处理 客户端 IFRAME      更新时间:2023-09-26

问题

我有一些 JavaScript 内容,我想将它们"沙盒"到 iframe 中:

<script type="text/javascript">
    doSomethingPotentiallyMalicious( // ideally, i want this to be able to run...
        top.document.getElementById('sensitive_information') // ...but want this to fail due to cross-domain permissions
    );
</script>

问题是,由于我们的 Web 应用程序的性质,我需要在包含 iframe 的父页面上内执行此操作,并且我需要以跨浏览器兼容的方式执行此操作。

数据网址...几乎但不完全

我能够通过数据网址在 iframe 中设置内容,从而在 Chrome 中获得所需的效果:

<iframe id="sandbox" src="data:text/html;charset=utf-8,%3Cscript%20type%3D%22text%2Fjavascript%22%3E%0A%20%20%20%20doSomethingPotentiallyMalicious(%20%2F%2F%20ideally%2C%20i%20want%20this%20to%20be%20able%20to%20run...%0A%20%20%20%20%20%20%20%20top.document.getElementById('sensitive_information')%20%2F%2F%20...but%20want%20this%20to%20fail%20due%20to%20cross-domain%20permissions%0A%20%20%20%20)%3B%0A%3C%2Fscript%3E"></iframe>

但是,数据 url 支持参差不齐,这需要跨浏览器工作。

Document.write获取内容,但缺乏跨域安全性

我可以将不安全的内容放在 javascript 转义字符串中,然后将其编写为 iframe 的内容:

<iframe id="sandbox" src="http://google.com/"></iframe>
<script>
    var unsafeContent = ''x3Cscript'x20type'x3D'x22text'x2Fjavascript'x22'x3E'x0A'x20'x20'x20'x20doSomethingPotentiallyMalicious'x28'x20'x2F'x2F'x20ideally,'x20i'x20want'x20this'x20to'x20be'x20able'x20to'x20run...'x0A'x20'x20'x20'x20'x20'x20'x20'x20top.document.getElementById'x28'x27sensitive_information'x27'x29'x20'x2F'x2F'x20...but'x20want'x20this'x20to'x20fail'x20due'x20to'x20cross'x2Ddomain'x20permissions'x0A'x20'x20'x20'x20'x29'x3B'x0A'x3C'x2Fscript'x3E'x0A'x0A';
    var sandbox = document.getElementById('sandbox');
    sandbox = (sandbox.contentWindow) ? sandbox.contentWindow : (sandbox.contentDocument.document) ? sandbox.contentDocument.document : sandbox.contentDocument;
    sandbox.document.open();
    sandbox.document.write(unsafeContent);
    sandbox.document.close();
</script>

这样做的问题是,一旦我将内容写入 iframe,跨域安全性显然不再存在(这意味着doSomethingPotentiallyMalicious函数可以访问父窗口中的所有内容)。

Document.write + Document.domain似乎也没有让我们到达那里。

我什至尝试根据之前的 SO 帖子更改document.domain(通过删除最左侧的域,使"www.example.com"变为"example.com"),但这似乎也没有强制执行跨域策略:

<iframe id="sandbox" src="http://google.com/"></iframe>
<script>
    // prepended to unsafeContent: document.domain = document.domain.replace(/^['w-]+'./,'');
    var unsafeContent = ''x3Cscript'x20type'x3D'x22text'x2Fjavascript'x22'x3E'x0A'x20'x20'x20'x20document.domain'x20'x3D'x20document.domain.replace'x28'x2F'x5E'x5B'x5Cw'x2D'x5D'x2B'x5C.'x2F,'x27'x27'x29'x3B'x0A'x20'x20'x20'x20doSomethingPotentiallyMalicious'x28'x20'x2F'x2F'x20ideally,'x20i'x20want'x20this'x20to'x20be'x20able'x20to'x20run...'x0A'x20'x20'x20'x20'x20'x20'x20'x20top.document.getElementById'x28'x27sensitive_information'x27'x29'x20'x2F'x2F'x20...but'x20want'x20this'x20to'x20fail'x20due'x20to'x20cross'x2Ddomain'x20permissions'x0A'x20'x20'x20'x20'x29'x3B'x0A'x3C'x2Fscript'x3E'x0A'x0A';
    var sandbox = document.getElementById('sandbox');
    sandbox = (sandbox.contentWindow) ? sandbox.contentWindow : (sandbox.contentDocument.document) ? sandbox.contentDocument.document : sandbox.contentDocument;
    sandbox.document.open();
    sandbox.document.write(unsafeContent);
    sandbox.document.close();
</script>
在这一点上,

我正在尝试做的事情在技术上是否可行?

我想知道window.postMessage是否有效。你可以设置一个 iframe,它评估它收到的第一条消息,将 javascript 注入其中。根据我链接的网站,它适用于Firefox,IE8 +,Opera,Safari和Chrome。希望这对您来说足够跨浏览器。移动设备可能存在问题。