2010-01-25 89 views
1

下面似乎是一个合理的运用__caller____caller__为什么不安全?

var foo=1; 
function a() { 
    var foo=2; 
    function b() { 
     var foo=3; 
     foo; // 3 
     this.foo; // 1, from global 
     __caller__.foo // 2 
    } 
    b(); 
} 
a(); // creates a's execution context 

然而,__caller__不可用。为什么不?如果可以使用this访问全局上下文/变量对象,那么为什么不是a的?

回答

4

Doc says

特殊属性__caller__,其返回从而允许以重构堆呼叫者的激活对象,是为安全起见移除。

很容易明白为什么这可能是浏览器中的安全灾难,其中大部分UI都是在JavaScript中实现的。想象一下你的一个函数是由附加函数或其他chrome调用的。您可以查看调用堆栈并读取调用者的(可能敏感的)变量,甚至可以将JavaScript值插入调用者函数中,这可能会颠覆他们去做违背用户意愿的事情。有效地,每个网页都会获得Chrome安全特权并完全危害浏览器。

你当然不应该在真正的JavaScript中使用它,因为它是一个非标准的仅用于Mozilla的实现细节,更不用说难以置信的丑陋。它没有你通常期望的JS的词汇行为。

+0

我不能使用'this'来访问浏览器本身的全局上下文。您所描述的安全缺陷似乎很容易解决,从不在全局范围内设置__caller__,因此从不提供对特权代码的引用。所以我没有看到一个问题,这导致我问这个问题。 – 2010-01-25 17:51:09

+0

你有词法范围和调用堆栈混淆。 '__caller__'会退回调用堆栈;它不需要到达与全局范围对应的激活对象。 – bobince 2010-01-25 18:40:10

+0

我的不好。 “...在提供特权代码的引用时从不设置它”。如果使用沙箱,它不是一个安全的灾难。或者是因为某些原因不重要? – 2010-01-26 02:40:53

1

我对这个问题并不是很熟悉,但是你试过arguments.callee.caller

在这里看到:Javascript how do you find the caller function?

+0

在'a();'上方加上'a.baz = 99'。现在,如果我们在b()中尝试'arguments.callee.caller.baz',我们会得到99.太好了 - 让我们使用'arguments.callee.caller.foo'!我们没有定义。拍摄 - 好吧,发生了什么事是'caller'指的是函数* object *,而'__caller__'指向变量对象('foo' = 2被附加到)。 – 2010-01-25 16:47:03

0

在你的榜样,你可以说,事情b应该能够解决的a主动实例的事情,它似乎是合理的,因为a封闭b。但如果不是这样的话,说你定义

function c() { 
     var foo='hedgehog'; 
     b(); 
    } 

这完全是另一回事,所以你的论点看起来像它适用于非常特殊的情况。

+0

特殊情况很有趣,有助于理解。 (如果你的c在全局范围内,那么它的'b'是未定义的,如果它在b中,那么我可能打算这么做 - 我可能会定义一个奇怪的递归函数,我需要检查最后一次递归的值。或者我可能想要选择定义一个变量的范围,或者打印一个堆栈跟踪。) – 2010-01-25 17:12:48

相关问题