2010-01-25 103 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