2010-01-25 6 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__ не доступен. Почему нет? Если глобальный объект context/variable можно получить с помощью this, то почему бы не a?

ответ

4

Doc says:

Специальная __caller__ свойство, которое возвращается объект активации вызывающего абонента таким образом, что позволяет восстановить стек, был удален по соображениям безопасности.

И легко понять, почему это может быть катастрофой безопасности в браузере, где большая часть пользовательского интерфейса реализована в JavaScript. Представьте, что у вас есть одна из ваших функций, называемая дополнительным или другим хром. Вы можете искать стек вызовов и считывать (потенциально чувствительные) переменные, или даже вводить значения JavaScript в функции вызывающего абонента, потенциально подрывая их, чтобы что-то делать с пожеланиями пользователя. Эффективно каждая веб-страница получит хром-привилегии безопасности и полностью скомпрометирует браузер.

Вы, конечно, никогда не должны использовать его в реальном JavaScript, потому что это была нестандартная деталь реализации Mozilla, не говоря уже о невероятно уродливой. У вас нет лексического поведения, которое вы обычно ожидаете от JS.

+0

Я не могу получить доступ к глобальному контексту самого браузера, используя 'this'. Обнаружение безопасности, о котором вы описали, казалось легко устраненным, никогда не устанавливая '__caller__' в глобальной области видимости, поэтому никогда не предоставляйте ссылку на привилегированный код. Поэтому я не вижу проблемы, которая заставляет меня задавать этот вопрос. –

+0

У вас есть лексические области и стек вызовов запутался. '__caller__' будет переходить через стек вызовов; он никогда не должен достигать объекта активации, соответствующего глобальному охвату. – bobince

+0

Мой плохой. «... никогда не устанавливая его, когда он предоставляет ссылку на привилегированный код». Это небезопасная катастрофа, если песочница просто тривиально. Или это почему-то нетривиально? –

1

Я действительно не знаком с этой темой, но вы пробовали arguments.callee.caller?

Смотрите здесь: Javascript how do you find the caller function?

+0

Добавьте 'a.baz = 99' прямо над' a(); '. Теперь, если мы попробуем 'arguments.callee.caller.baz' внутри b(), получим 99. Отлично - давайте будем использовать' arguments.callee.caller.foo'! Мы становимся неопределенными. Shoot - хорошо, что произошло, что 'caller' ссылается на функцию * object *, а' __caller__' ссылается на объект переменной (к которому привязан 'foo' = 2). –

0

В вашем примере, вы можете утверждать, что вещи в b должны быть в состоянии решать вещи в активном экземпляре a, и представляется разумным, поскольку a охватывает b. Но если бы это было не так, что вы определить

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

что-то совершенно другое, так что ваш аргумент выглядит, как он относится к довольно частному случаю.

+0

Особые случаи - это забава и помощь с пониманием. (Если ваш c находится в глобальной области, то его 'b' не определено. Если он находится внутри b, то я, вероятно, намереваюсь это сделать - я могу определить странную рекурсивную функцию, где мне нужно проверить значения из последней рекурсии. Или я могу выбрать, в какой области я определяю переменную. Или распечатать трассировку стека.) –

Смежные вопросы