【问题标题】:Making a Same Domain iframe Secure使同一域 iframe 安全
【发布时间】:2013-05-22 00:05:11
【问题描述】:

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...,但我的函数停止工作,我无法找出原因。

注意:

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

【问题讨论】:

  • 如果您将iframedocument.domain 设置为其他内容怎么办?因此,如果没有postMessage,他们将无法与其他人交谈。只是一个想法。我记得如果你将它们都设置为相同的值,你可以让它们说话,所以我想知道做相反的事情是否会产生相反的结果。我在摆弄小提琴中的一些东西;这是一个有趣的问题,我喜欢你的方法:)
  • @Ian 我可以在 iframe 的代码中自己更改 document.domain 吗?如果我这样做了,我能保证它不会被恶意代码改回来吗?
  • 是的,我很确定你可以。好吧,您也可以将父页面中的值更改为随机/唯一的值,然后 iframe 脚本很难猜测和匹配它。我想我应该在评论之前考虑整个场景,但这可能是你可以玩弄的东西。我忘记了设置它的意义以及它的实际变化,我只记得看到它被同步,以便窗口和 iframe 可以交谈(通过什么方式,我不记得了)

标签: javascript iframe security


【解决方案1】:

你不能真正删除引用,设置 null 只会默默地失败,总有办法获得对父 dom 的引用。

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

不过你可以查看Caja/Cajita

【讨论】:

    【解决方案2】:

    tl;博士没有

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

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

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

    【讨论】:

    • 怎么样?它有效 with WebWorkers ,阻止我删除 iframe 内对父窗口的所有引用的核心问题是什么?我试过这样做但没有成功,但我想确信这是不可能的。在执行第二个脚本标记之前,您能否给我一个示例,说明我无法在此处设置为 null jsfiddle.net/Xwu3S,这会危及安全性?在你的例子中,我不能做window.top = null; 吗?
    • 我不知道,你在问三个问题。你指的是什么问题?
    • 我只问一件事:“为什么答案是否定的?”,您的论点是脚本可能会窃取信息,您可以通过示例 window.top. ... 来展示它。我是说我可以将window.top 设置为空。我想看看为什么这对我没有帮助。我不是说你错了,我只是想了解内在的问题是什么。
    • 我不知道.. 可能有办法绕过它。对于一个你可以使用window.parent 直到你到达顶部。你也许也可以阻止它,但也许也有办法解决这个问题。至少你可以做window.location.href 并将用户发送到任何地方。你打算怎么阻止它?它变成了一场你会输的猫捉老鼠游戏,因为老鼠只需要得分一次。
    • 有趣的点。我只关心外部 JSONP 服务可以冻结浏览器,他们可以导航 iframe,他们可以在其中移动内容。这是一个不可见的 iframe,他们可以轻松运行while(true){},这会挂起浏览器,因为 iframe 在同一个线程上运行。我唯一真正关心的是安全性。我不想让 iframe 以任何方式执行主窗口中的 DOM 或 JavaScript 变量。只要我保证用户数据的安全,这就是我的胜利。
    猜你喜欢
    • 2014-07-20
    • 2012-07-18
    • 2010-10-25
    • 1970-01-01
    • 1970-01-01
    • 2010-09-18
    • 2019-01-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多