2012-03-12 116 views
2

我有一个包含iframe(相同来源)的窗口,因此来自此iframe的脚本可以通过简单引用top.foo来访问顶层窗口的属性。我想授予对这些属性的访问权限,并通过黑名单隐藏其他属性。从iframe中的脚本隐藏对象的某些属性

这是我到目前为止有:

(function(){ 
    var private = PrivateObject; 
    Object.defineProperty(window, 'PrivateObject', { 
     get: function getter() { 
      if (!(getter.caller instanceof Function)) { 
       throw 'You can\'t access PrivateObject from the iframe'; 
      } 
      return private; 
     }, 
     set: function setter(x) { 
      if (!(setter.caller instanceof Function)) { 
       throw 'You can\'t access PrivateObject from the iframe'; 
      } 
      private = x; 
     }, 
    }); 
})(); 

这背后的基本理念是,f.caller instanceof Function应检测外来窗口对象的调用,因为window1.Function !== window2.Function

但是这does not work如果访问器是从顶级代码调用,其中f.caller === null。任何解决方案

+0

对不起,如果是天真的,但如果.caller为null不会从顶级代码工作?异常不会被抛出? – dave 2012-03-12 19:31:10

+0

问题是,用这种方法你会得到误报和误报。所以我正在寻找一种解决方案,允许从父级的顶级代码访问,同时阻止访问iframe的顶级代码。 – user123444555621 2012-03-12 20:50:03

回答

0

现在,我已经决定去与下面的办法,因为我不认为这是可以检测的顶级呼叫:如果有人想出了一个更好的解决方案

/** 
* Hide objects from access from other window objects. For example, this may be used to prevent access to 
* top.Ext from scipts inside iframes. 
* <strong>Warning:</strong> This does not work reliably, since calls from top-level code cannot be detected. 
* You may either <strong>allow all</strong> top-level access (from top and other windows), or <strong>disallow all</strong> top-level access. 
* Also remember that objects may have indirect references. 
* @param {Object} object The object whose properties shall be hidden 
* @param {Array|String} properties A comma-separated list or an array of property names 
* @param {Boolean} allowTopLevel <tt>true</tt> to allow access from top-level code. Defaults to <tt>false</tt> 
*/ 
hideObjectsFromFrames = function (object, properties, allowTopLevel) { 
    if (typeof properties == 'string') { 
     properties = properties.split(/ *, */); 
    } 
    Ext.each(properties, function (property) { 
     var orig = object[property]; 
     if (allowTopLevel) { // checking outside the accessors improves performance 
      Object.defineProperty(object, property, { 
       get: function g() { 
        if (g.caller && !(g.caller instanceof Function)) { 
         throw 'Security error. Attempt to access ' + property + ' from foreign window'; 
        } 
        return orig; 
       }, 
       set: function s(x) { 
        if (s.caller && !(s.caller instanceof Function)) { 
         throw 'Security error. Attempt to overwrite ' + property + ' from foreign window'; 
        } 
        orig = x; 
       } 
      }); 
     } else { 
      Object.defineProperty(object, property, { 
       get: function g() { 
        if (!(g.caller instanceof Function)) { 
         throw 'Security error. Attempt to access ' + property + ' from foreign window'; 
        } 
        return orig; 
       }, 
       set: function s(x) { 
        if (!(s.caller instanceof Function)) { 
         throw 'Security error. Attempt to overwrite ' + property + ' from foreign window'; 
        } 
        orig = x; 
       } 
      }); 
     } 
    }); 
}; 

,请让我知道!

+0

FWIW,Safari 5.0中存在一个阻止'allowTopLevel'正常工作的错误:https://bugs.webkit.org/show_bug.cgi?id = 45480 – user123444555621 2012-03-20 09:06:57