6

问题

我有一些想要“沙盒”到 iframe 中的 javascript 内容:

<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 的父页面上内联执行此操作,并且我需要以跨浏览器兼容的方式执行此操作。

数据 URL...几乎但不完全

通过数据 url 在 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 post更改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>

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

4

1 回答 1

2

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

于 2012-08-12T21:03:54.420 回答