使相同的域iframe安全

时间:2013-05-22 00:05:12

标签: javascript iframe security

tl; dr 我可以安全地在iframe上执行不受信任的脚本吗?

背景故事:

我正在尝试make secure JSONP requests。许多旧的浏览器不支持Web Workers,这意味着我提出的当前解决方案并不是最佳的。

我想我可以创建一个<iframe>并在其中加载一个脚本。该脚本将执行JSONP请求(创建脚本标记),该请求会将消息发布到主页面。主页面将获取消息,执行回调并销毁iframe。我设法do this sort of thing

function jsonp(url, data, callback) {
    var iframe = document.createElement("iframe");
    iframe.style.display = "none";
    document.body.appendChild(iframe);

    var iframedoc = iframe.contentDocument || iframe.contentWindow.document;
    sc = document.createElement("script");

    sc.textContent = "(function(p){ cb = function(result){p.postMessage(result,'http://fiddle.jshell.net');};})(parent);";
    //sc.textContent += "alert(cb)";
    iframedoc.body.appendChild(sc);
    var jr = document.createElement("script");

    var getParams = ""; // serialize the GET parameters
    for (var i in data) {
        getParams += "&" + i + "=" + data[i];
    }

    jr.src = url + "?callback=cb" + getParams;
    iframedoc.body.appendChild(jr);
    window.onmessage = function (e) {
        callback(e.data);
        document.body.removeChild(iframe);
    }

}

jsonp("http://jsfiddle.net/echo/jsonp/", {
    foo: "bar"
}, function (result) {
    alert("Result: " + JSON.stringify(result));
});

问题在于,由于iframe位于同一个域中,因此注入的脚本仍然可以通过.top.parent等访问外部作用域。

有没有办法创建一个无法访问父作用域数据的iframe?

我想创建一个iframe,其中通过脚本标记添加的脚本将无法访问父窗口(和DOM)上的变量。我试过像top=parent=null这样的东西,但我真的不确定这是否足够,可能还有其他的解决方法。我尝试运行for ... in循环,但我的功能停止工作,我无法找到原因。

注意:

我最了解WebWorkers是一个更好的隔离环境。我知道JSONP是一种“糟糕”的技术(我甚至让some random guy告诉我他今天从未使用过它)。我正在尝试为 执行JSONP查询的方案创建一个安全的环境。

2 个答案:

答案 0 :(得分:1)

tl; dr no

任何不受信任的脚本都可以窃取cookie(如会话ID!)或从DOM读取信息,如信用卡输入字段的值。

JavaScript依赖于所有代码都是可信代码的安全模型。任何从其他域访问的尝试都需要明确的白名单。

如果您想对iframe进行沙盒处理,则可以从其他域提供该页面。这意味着您不能共享会话或进行任何类型的通信,因为它可能被滥用。这就像包括一个不相关的网站。即使这样,如果您允许不受信任的JavaScript,也有可能被滥用。例如,您可以执行:window.top.location.href = 'http://my.phishing.domain/';,用户可能不会注意到重定向。

答案 1 :(得分:1)

你无法真正删除引用,设置null只会默默地失败,并且始终有办法获得对父dom的引用。

无法删除frameElementframeElement.defaultView等参考文献。尝试这样做会默默地失败或抛出异常,具体取决于浏览器。

你可以查看Caja/Cajita