是“iframe沙盒”技术安全? [英] Is the "iframe sandbox" technique safe?

查看:149
本文介绍了是“iframe沙盒”技术安全?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

更新:由于未回答,我稍微更改了问题。关于在下面链接的Dean的博客上的帖子的评论表明这种技术不工作在Safari。



我现在的问题是:下面描述的技术是否在现代浏览器中工作,特别是有人可以确认它在Safari中是否有效?



这是最近的博文。它说一次:


沙盒的本地人...支持各种浏览器,包括... Safari 2.0 +


...但后来说iframe技术是除了Safari之外的所有主流浏览器都支持的,他的回退包括做一些奇怪的东西与伪造的构造函数和 __ proto __ 似乎有点hacky。



我几乎发现很难相信两不同的窗口实际上可以共享相同的,比如说Object.prototype。跨网域iframe会发生什么情况?如果我在一个框架中修改原型,在其他框架中的原型是否修改?这似乎是一个明显的安全问题。有人请解释一下这种情况。



*由work我的意思是 My.Object!= Object ,所以原型可以在一个窗口中修改而不影响其他窗口。






原始帖子



我知道这已经被问过,但我有一个特定的解决方案,我想知道这种类型的解决方案是否已经讨论过,在哪里我可以学习如何可靠和广泛接受。 / p>

问题是如何在javascript中扩展本机类型,而不会弄乱类型本身,所以只是改变Array.prototype是不好的(也许其他代码是用于.. in数组)。创建一个假构造函数返回一个带有一些函数的本地数组似乎不是一个好的解决方案,实际上扩展本机对象似乎更好。但是你不能做原生类型的普通javascript虚拟函数原型switcharoo样式扩展,因为当你尝试调用原生函数时,你会得到类似push is not generic的错误。



所以,我想到的解决方案是这样的:创建另一个窗口,在该窗口中添加原生构造函数的原型,并在程序中使用这些构造函数。



此示例使用 Array 扩展为 My.Array / code>函数和字符串作为 My.String code> function。

  var My =(function(){

// create一个iframe获取一个单独的全局作用域
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沙盒



http://dean.edwards.name/weblog/2006/11/hooray/\">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 将返回主要的窗口数组取决于浏览器...),可能有更多。所以我会说这是很不安全。



这是一个overkill反正,似乎太多的工作,没有真正的收益。

 <!DOCTYPE html> 
< html>
< head>
< / head>
< body>
< script type =text / javascript>
(function(){
var ifr = document.createElement(iframe),
callbacks = [],
isReadyState =readyStatein 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 callbacks [i] $ b}

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; //将此变更为DOMReady或任何
})()


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>


Update: Since this is unanswered, I'm changing the question slightly. Comments on the post on Dean's blog linked below indicate this technique does not work in Safari.

My question now is: does the technique described below work* in modern browsers, and in particular can someone confirm whether it works in Safari?

Here's a more recent blog post. It says at one point:

Sandboxed natives ... are supported in a variety of browsers, including ... Safari 2.0+

...but later says that the iframe technique is "supported by all major browsers except Safari," and the fallback he shows involves doing some weird stuff with faked constructors and __proto__ that seems a bit hacky.

I almost find it hard to believe that two different windows could actually share the same, say, Object.prototype. What happens with cross-domain iframes? If I modify prototypes in one frame, do the prototypes in the other frame get modified? This seems like an obvious security concern. Someone please shed some light on this situation.

* By "work" I mean My.Object != Object, so the prototypes can be modified in one window without affecting the other.


Original post

I know this has been asked before, but I have a specific solution in mind, and I want to know if this type of solution has been discussed before and where I might learn how reliable and well-accepted it is.

The question is how to extend native types in javascript without actually messing with the types themselves, so just altering Array.prototype is no good (maybe other code is using for..in with arrays). Creating a fake constructor that returns a native array with some functions tacked on doesn't seem like a good solution either, actually extending the native objects seems better. But you can't do the normal javascript dummy function prototype switcharoo style extension with native types either, because you'll get errors like "push is not generic" when you try to call native functions.

So, the solution I have in mind works like this: create another window, add functionality to prototypes of native constructors in that window, and use those constructors in your program.

This example extends Array as My.Array with an each function and String as My.String with an alert function.

    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;

    }());

Again, my question is whether this approach has been discussed before, what it's called, where I can find more information, etc. I'd like to know if there is a cleaner way to get another global scope without using an iframe, or if it's possible this will fail for some reason in certain javascript engines, or if anyone thinks it's a particularly bad idea or whatever.


Update: I guess people are calling this kind of thing an iframe sandbox, not to be confused with the HTML5 iframe sandbox attribute.

related:

http://dean.edwards.name/weblog/2006/11/hooray/

http://webreflection.blogspot.com/2008/03/javascript-arrayobject.html

解决方案

I ran this page in various browsers (Safari, Opera, IE7-9, Chrome, Firefox) and got consistent results with everything but firefox, in firefox the prototypes are sandboxed so that's good but the second test fails for some reason in firefox. The iframe prototype isn't immediately augmented. But this doesn't matter if you didn't mean to augment it anyway. You could try running it in more browsers to test.

Note that this doesn't really test any of the quirks for example (My.Array().slice would return the main window arrays depending on browser...) and there could be more. So I would say it's pretty unsafe.

It's an overkill anyway and seems too much work for no real gain.

<!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>

这篇关于是“iframe沙盒”技术安全?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆