2014-01-09 3 views
2

Я пытаюсь выполнить кусок кода в пустом изолированном контексте выполнения в JavaScript. В приведенном ниже примере я пытаюсь выделить область выполнения . То, что я хочу сделать, это выполнить функцию в условиях, когда никаких глобальных переменных не находятся.Изолированный контекст выполнения в JavaScript

(function() { 
    'use strict'; 

    var scope = Object.create(null); 
    var isolated = function() { 
    'use strict'; 
    console.log(document); // Trying to get undefined 
          // but traces `document`. 
    }; 

    isolated.call(scope); 
})(); 

Я думал, что это было просто аннулирует глобальные переменные, но есть слишком много!

var isolated = function(window, document, location /* etc */) { 
    // ... 
}; 

isolated.call(scope, undefined, undefined, undefined /* etc */); 

Есть ли лучший способ сделать это?

ответ

4

Eсть no good способ сделать это в самом javascript (но см. Gareth Hayes ответ на другой вариант).

Есть пара плохих путей.

(function() { 
    var scope = Object.create(null); 
    var obscurer = {}; 
    for (var key in this) { 
    obscurer[key] = undefined; 
    } 

    with (obscurer) { 
    var isolated = function() { 
     'use strict'; 
     console.log(document); 
    }; 
    } 

    isolated.call(scope); 
})(); 

Обратите внимание, что вы действительно получите ошибку, потому что консоль не определен, а не документ, хотя вы можете исправить это, не блокируя «консоли» в объекте туманней. Вероятно, вы обнаружите, что вам нужна целая куча больше глобальных, чем вы поняли.

Вы также блокируете только перечислимые свойства окна. Если вам станет известно о неизмеримых свойствах, которые вы хотите заблокировать, вам придется добавить их к темникам.

Конечно, используя with означает, что вы не можете использовать строгий режим больше, как хорошо, и все будут смотреть свысока на вас ..

Есть более интересные варианты, если вы работаете в узле, а чем браузер.

+0

Window.prototype.alert.call (окно, 1) обходит эту песочницу. –

+0

Я получаю «TypeError: window undefined», но да, я бы не стал считать этот метод безопасным *. Насколько я знаю, вы не можете создать безопасную песочницу без разбора кода ввода. И даже тогда есть много ошибок, которые могут быть сделаны (например, люди часто забывают, что конструктор Function позволяет им использовать код eval). – kybernetikos

+0

Это особый вектор для Firefox. –

2

Используйте мой парсер MentalJS, чтобы изолировать окружающую среду. Затем вы можете выбрать, к каким объектам/переменным, к которым он имеет доступ, путем настройки кода.

http://businessinfo.co.uk/labs/MentalJS/MentalJS.html

http://code.google.com/p/mentaljs/

По умолчанию он позволяет получить доступ к документу, но вы можете предотвратить это, настроить среду здесь http://code.google.com/p/mentaljs/source/browse/trunk/MentalJS/javascript/Mental.js#260, то вы можете выбрать, если они имеют доступ к математике и т.д.

0

Это может быть сделано без ECMA6 с использованием IIFE, который содержит ваш код защиты от надежных потребностей, в который вы вводите код ненадежного кода потребности (см. Пример).

(function(injectedFunction) { 
    /* Trusted code, that needs protection from untrusted code access */ 
    var hostingFuncPrivatePrimitive = "Hello there"; 
    var hostingFuncPrivateObject = { 
     this_is_mine: true 
    }; 

    var sharedPrimitive = 'This is shared'; 
    var sharedObject = {}; 

    // Running the untrusted code: 
    injectedFunction(sharedPrimitive, sharedObject); 

    console.log("sharedObject is: " + JSON.stringify(sharedObject)); 
    console.log("hostingFuncPrivateObject is: " + 
     JSON.stringify(hostingFuncPrivateObject)); 
})(

(function(primitiveArg, objArg) { 
    /* Untrusted code that needs isolation */ 

    // 1. using primitive (legal) 
    console.log('primitiveArg is: ' + primitiveArg); 

    // 2. Writing value to given objArg (legal): 
    objArg.mumu = 'mimi'; 

    // 3. Trying to access host function variables (illegal) 
    try { 
     console.log('hostingFuncPrivatePrimitive is:' + 
      hostingFuncPrivatePrimitive); 
     hostingFuncPrivateObject.this_is_mine = false; 
    } catch (e) { 
     console.log(e); 
    } 
}) 

); 

Если вы поместите выше в консоли Chrome, вы получите:

primitiveArg is: This is shared 
    VM117:29 ReferenceError: hostingFuncPrivatePrimitive is not defined 
      at <anonymous>:26:17 
      at <anonymous>:11:5 
      at <anonymous>:16:3 
    VM117:12 sharedObject is: {"mumu":"mimi"} 
    VM117:13 hostingFuncPrivateObject is: {"this_is_mine":true} 

P.S .: Я знаю, что я опоздал на вечеринку, но, возможно, это помогает никому.

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