【问题标题】:Chrome app: accessing sandboxed iframe from parent windowChrome 应用程序:从父窗口访问沙盒 iframe
【发布时间】:2013-04-24 18:03:34
【问题描述】:

我在我的谷歌浏览器应用程序中使用了 knockoutjs。为了能够使用淘汰赛,我必须将真正的 application.html 定义为 Sandox 页面,并将其作为 iframe 包含在虚拟容器中。应用结构如下:

- container.html
|
+-- application.html as iframe 
   |
   +-knockout and application.js

iframe 定义如下:

  <iframe src="application.html" frameborder="0"  
            sandbox="allow-same-origin allow-scripts" ></iframe>

跑步

document.getElementsByTagName("iframe")[0]

在 container.html 上的检查工具中会引发以下错误。

Sandbox access violation: Blocked a frame at "chrome-extension://hllbklabnppjkmnngfanldbllljfeaia" 
from accessing a frame at "chrome-extension://hllbklabnppjkmnngfanldbllljfeaia".  
The frame being accessed is sandboxed and lacks the "allow-same-origin" flag.

如何从其父级访问 iframed 文档?

【问题讨论】:

    标签: javascript google-chrome iframe sandbox google-chrome-app


    【解决方案1】:

    做这样的事情:

    manifest.json

      "sandbox": {
        "pages": ["my_ui.html"]
      }
    

    my_ui.html

      <script type="text/javascript" src="knockout-1.2.3.4.js"></script>
      <script type="text/javascript" src="my_ui.js"></script>
    

    my_ui.js

    this.onSomethingChange = function() {
      window.top.postMessage(
        { command: 'please-do-something', myArgument: this.myArgument() }, '*');
    };
    

    container.html

      <script type="text/javascript" src="container.js"></script>
      <iframe id="knockoutFrame" src="my_ui.html"></iframe>
    

    container.js

      window.addEventListener('message', function(event) {
        var kocw = document.getElementById('knockoutFrame').contentWindow;
        var anotherContentWindow = // etc.
        var dest;
    
        if (event.source == kocw) {
          // The knockout iframe sent us a message. So we'll forward it to our
          // app code.
          dest = anotherContentWindow;
        }
        if (event.source == anotherContentWindow) {
          // Our app code is responding to the knockout message (or initiating
          // a conversation with that iframe). Forward it to the knockout code.
          dest = kocw;
        }
        if (dest == null) {
          console.log('huh?');
        }
    
        // This makes container.js like a gatekeeper, bouncing valid messages between
        // the sandboxed page and the other page in your app. You should do
        // better validation here, making sure the command is real, the source
        // is as expected for the kind of command, etc.
        dest.postMessage(event.data, '*');
      }
    

    您的陈述“我必须将真正的 application.html 定义为沙盒页面并将其作为 iframe 包含在虚拟容器中”可能不是您想要的。这个想法是将尽可能小的东西沙箱化,将消息发送到验证消息的网守页面,并让网守将窄消息转发到您的未沙箱化应用程序逻辑。如果你只是把所有东西都塞进沙盒,你就违背了沙盒的目的。

    免责声明:我没有从安全角度仔细检查此代码。您需要假设恶意消息来自沙盒(或其他地方,就此而言),并尽您所能解决该威胁。

    【讨论】:

    • 感谢您的回复。我正在做几乎完全相同的事情。我的整个应用程序需要淘汰,并且需要访问一些其他扩展程序无法使用的 api。我正在使用与您的代理非常相似的代理在应用程序 iframe 和背景页面之间传输消息。 “document.getElementById('knockoutFrame').contentWindow”是我在代理代码中得到“沙盒访问冲突”错误的地方。
    【解决方案2】:

    找出罪魁祸首。这是我的 proxy.js,它包含在 container.html 中,用作在应用程序 iframe 和 background.js 之间传输消息的桥梁。以下部分是侦听来自 iframe 的消息的部分。

    window.addEventListener("message",
        function(evt){
            console.log(evt); <= this is the problem
            var iframe = document.getElementById("application").contentWindow; <= not this one
            if (evt.source == iframe) {
                return chrome.runtime.sendMessage(null, evt.data);
            }
        }
    );
    

    我不认为 console.log 会导致问题。相反,我怀疑来自 document.getElem.. 行。因为尝试在应用程序的检查窗口中运行该代码会引发相同的错误。

    但似乎console.log(控制台似乎属于container.html的范围)访问了事件对象的一些内部,这些内部并不意味着可以在iframe的范围之外访问(这解释了为什么我在inspect中得到相同的错误安慰)。删除 console.log 行为我解决了这个问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-11-22
      • 1970-01-01
      • 2012-04-05
      • 2018-12-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-25
      相关资源
      最近更新 更多