使同一域iframe安全

Making a Same Domain iframe Secure

本文关键字:iframe 安全      更新时间:2023-09-26

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

背景故事:

我正在尝试使安全的JSONP请求。许多旧的浏览器不支持Web worker,这意味着我目前提出的解决方案不是最佳的。

我想我可以创建一个<iframe>并在其中加载一个脚本。该脚本将执行一个JSONP请求(创建一个脚本标记),该请求将向主页面发布一条消息。主页面将获取消息,执行回调并销毁iframe。我已经设法做过这种事了。

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这样的东西,但我真的不确定这是否足够,可能还有其他的解决方案。我试着运行一个…在循环中,但是我的函数停止工作,我无法找出原因。

注意:

我知道WebWorkers是一个更好的隔离环境。我知道JSONP是一个"坏"字。技术(我甚至有一些随机的人告诉我他今天永远不会使用它)。我正试图为您执行JSONP查询的场景创建一个安全环境。

你不能真的删除引用,设置null只会默默地失败,总有一种方法可以获得父dom的引用。

不能删除frameElementframeElement.defaultView等引用。根据浏览器的不同,尝试这样做会以静默方式失败或抛出异常。

你可以看看Caja/Cajita。

;

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

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

如果你想沙箱你的iframe,你可以从另一个域提供页面。这确实意味着你不能共享会话或进行任何形式的交流,因为它可能被滥用。这就像包含一个不相关的网站。即使这样,如果允许不受信任的JavaScript,也有可能被滥用。例如,您可以执行:window.top.location.href = 'http://my.phishing.domain/';,用户可能不会注意到重定向