是“iframe沙盒”技术安全
Is the "iframe sandbox" technique safe?
Update:由于这是没有答案的,我稍微改变了这个问题。下面链接的Dean博客上的评论指出,这种技术在Safari中不起作用。
我现在的问题是:下面描述的技术在现代浏览器中工作吗?特别是有人能确认它是否在Safari中工作吗?
这是最近的一篇博客文章。它在某处说:
沙盒原生体…在各种浏览器中都支持,包括…Safari 2.0 +
…但后来说iframe技术"被所有主流浏览器支持,除了Safari",他展示的退路包括用伪造的构造函数和__proto__
做一些奇怪的事情,看起来有点黑客。
我几乎很难相信两个不同的窗口实际上可以共享相同的,比如Object.prototype。跨域iframe会发生什么?如果我修改一个框架中的原型,另一个框架中的原型会被修改吗?这似乎是一个明显的安全问题。有人能解释一下这个情况吗?
*这里的"工作"指的是My.Object != Object
,所以原型可以在一个窗口修改而不影响另一个窗口。
原始文章
我知道以前有人问过这个问题,但我心中有一个具体的解决方案,我想知道这种解决方案以前是否讨论过,我可以从哪里了解到它是多么可靠和被广泛接受。
问题是如何在javascript中扩展原生类型而不实际干扰类型本身,所以只是改变Array。原型是不好的(也许其他代码使用for..in与数组)。创建一个返回带有一些函数的本地数组的假构造函数似乎也不是一个好的解决方案,实际上扩展本地对象似乎更好。但是你也不能用原生类型做普通的javascript虚拟函数原型切换样式扩展,因为当你尝试调用原生函数时,你会得到像"push is not generic"这样的错误。
因此,我想到的解决方案是这样的:创建另一个窗口,在该窗口中向本机构造函数的原型添加功能,并在程序中使用这些构造函数。
本例扩展Array
为My.Array
,扩展each
函数,扩展String
为My.String
,扩展alert
函数。
var My = (function(){
// create an iframe to get a separate global scope
var iframe = document.createElement('iframe');
iframe.style.height = '0px';
iframe.style.width = '0px';
iframe.style.border = 'none';
iframe.style.position = 'absolute';
iframe.style.left = '-99999px';
document.documentElement.appendChild(iframe);
var My = iframe.contentWindow;
My.String.prototype.alert = function(){
alert(this);
}
My.Array.prototype.each = function(callback){
for (var i=0, l=this.length; i<l; i++) {
callback(this[i], i);
}
}
return My;
}());
我的问题是以前是否讨论过这种方法,它叫什么,我在哪里可以找到更多的信息,等等。我想知道是否有一个更干净的方法来获得另一个全局作用域,而不使用iframe,或者如果有可能在某些javascript引擎中由于某种原因而失败,或者如果有人认为这是一个特别糟糕的主意或其他什么。
更新:我猜人们把这种东西称为iframe沙盒,不要与HTML5 iframe沙盒属性混淆。
相关:http://dean.edwards.name/weblog/2006/11/hooray/http://webreflection.blogspot.com/2008/03/javascript-arrayobject.html我在各种浏览器(Safari, Opera, IE7-9, Chrome, Firefox)上运行了这个页面,除了Firefox之外,所有的浏览器都得到了一致的结果。在Firefox中,原型是沙盒的,所以这很好,但是由于某种原因,第二个测试在Firefox中失败了。iframe原型不会立即得到增强。但如果你不打算增广它,这也没关系。你可以试着在更多的浏览器中运行它来测试。
注意,这并没有真正测试任何怪癖,例如(My.Array().slice
将返回主要的window
数组取决于浏览器…),可能还有更多。所以我想说这是非常不安全的。
不管怎么说,这都是小题大做,似乎做了太多的工作却没有真正的收获。
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<script type="text/javascript">
(function(){
var ifr = document.createElement("iframe"),
callbacks = [],
hasReadyState = "readyState" in ifr;
ifr.style.display = "none";
document.body.appendChild(ifr);
ifrDoc = ifr.contentWindow.document;
ifrDoc.open();
ifrDoc.write( "<!DOCTYPE html><html><head></head><body>"+"<"+"script"+">var w = this;"+"</"+"script"+">"+"</body></html>");
ifrDoc.close();
if( hasReadyState ) {
ifr.onreadystatechange = function(){
if( this.readyState === "complete" ) {
fireCallbacks();
}
};
}
function fireCallbacks(){
var i, l = callbacks.length;
window.My = ifr.contentWindow.w;
for( i = 0; i < l; ++i ) {
callbacks[i]();
}
callbacks.length = 0;
}
function checkReady(){
if( hasReadyState && ifr.readyState === "complete" ) {
fireCallbacks();
}
else if( !hasReadyState ) {
fireCallbacks();
}
}
window.MyReady = function(fn){
if( typeof fn == "function" ) {
callbacks.push( fn );
}
};
window.onload = checkReady; //Change this to DOMReady or whatever
})()
MyReady( function(){
My.Object.prototype.test = "hi";
var a = new My.Object(),
b = new Object();
console.log( Math.random(), My.Object !== Object && b.test !== "hi", a.test === "hi" );
});
</script>
</body>
</html>
如果你有两个不同的框架,它们的内容是从不同的域加载的,那么出于明显的安全原因,没有现代浏览器会允许它们之间在JavaScript级别上进行任何交互。你最好的办法当然是设置一个测试,看看自己会发生什么,但我很确定,你所描述的应该是安全的,在大多数浏览器。
- 如何在读取XLS/XLSX本地文件时,使用IE的javascript代码启用未标记为安全的ActiveX控件
- 使用javascript存储变量的最安全方式
- 是否存在React Native“;WEB代码安全防护”;
- 内容安全策略:页面's设置阻止加载资源
- 如何通过安全的https连接在javascript中使用基于soap xml的Web服务
- 导致内容安全策略(CSP)冲突错误的本地jquery.js文件
- 如何在Google chrome安全首选项文件中创建扩展安全哈希代码
- 用于发现哪个JS/jQuery脚本正在冻结页面的工具或技术
- ES6 模板文字是否比 eval 更安全
- CORS保持在SecurityError上:操作不安全
- 旋转木马;启用内容安全策略时无法工作
- 从自己的安全系统中重新找回自己
- 关于ajax的安全问题
- 如何使用app和secret进行安全的解析初始化
- JavaScript运行时事件循环现有技术
- 是一个javascript bookmarklet,可以设置破坏跨域安全的域cookie
- 最安全的javascript JSON内联技术
- 创建Undercore中使用的安全参考对象技术
- 是“iframe沙盒”技术安全
- 有哪些技术可以促进Javascript中的安全重构?