6

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

背后故事:

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

我想我可以在其中创建<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 位于同一域中,因此注入的脚本仍然可以通过.topor.parent等​​访问外部范围。

有什么方法可以创建一个无法访问父范围数据的 iframe?

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

笔记:

我知道最好的 WebWorkers 是一个更好的隔离环境。我知道 JSONP 是一种“糟糕”的技术(我什至有一些随机的人告诉我他今天永远不会使用它)。我正在尝试为必须执行 JSONP 查询的场景创建一个安全的环境。

4

2 回答 2

1

tl;博士没有

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

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

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

于 2013-05-22T00:08:54.767 回答
1

您不能真正删除引用,设置 null 只会默默地失败,并且总有一种方法可以获取对父 dom 的引用。

不能删除诸如此类frameElement的引用。frameElement.defaultView尝试这样做会静默失败或抛出异常,具体取决于浏览器。

不过,您可以查看Caja/Cajita

于 2013-05-30T14:46:44.530 回答