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,其中通过脚本标记添加的脚本将无法访问父窗口(和DOM)上的变量。我试过像top=parent=null
这样的东西,但我真的不确定这是否足够,可能还有其他的解决方法。我尝试运行for ... in循环,但我的功能停止工作,我无法找到原因。
注意:
我最了解WebWorkers是一个更好的隔离环境。我知道JSONP是一种“糟糕”的技术(我甚至让some random guy告诉我他今天从未使用过它)。我正在尝试为 执行JSONP查询的方案创建一个安全的环境。
答案 0 :(得分:1)
tl; dr no
任何不受信任的脚本都可以窃取cookie(如会话ID!)或从DOM读取信息,如信用卡输入字段的值。
JavaScript依赖于所有代码都是可信代码的安全模型。任何从其他域访问的尝试都需要明确的白名单。
如果您想对iframe进行沙盒处理,则可以从其他域提供该页面。这意味着您不能共享会话或进行任何类型的通信,因为它可能被滥用。这就像包括一个不相关的网站。即使这样,如果您允许不受信任的JavaScript,也有可能被滥用。例如,您可以执行:window.top.location.href = 'http://my.phishing.domain/';
,用户可能不会注意到重定向。
答案 1 :(得分:1)
你无法真正删除引用,设置null只会默默地失败,并且始终有办法获得对父dom的引用。
无法删除frameElement
和frameElement.defaultView
等参考文献。尝试这样做会默默地失败或抛出异常,具体取决于浏览器。
你可以查看Caja/Cajita。