Я работаю над проектом, который позволит пользователям загружать код для изменения поведения частей приложения. В этом сценарии я использовал предложение with
, чтобы не дать их коду изменить что-либо вне области, с которой я хочу, чтобы они возились. (Упрощенная) часть кода, которую я использую для этого:
// this code is only executed once
var localScope = {
build: undefined,
// this is where all of the values I want to hide go; the list is rather long
window: undefined,
console: undefined,
...
};
with(localScope) {
build = function(userCode) {
eval('var builtFunction = function(options) {' + userCode + '}');
return builtFunction;
}
}
var build = localScope.build;
delete localScope.build;
// this is how I use the build method
var userCode = 'return "Hello, World!";';
var userFunction = build(userCode);
Этот код (в некоторой степени) гарантирует, что пользовательский код не имеет доступа ни к каким объектам глобальной области, таким как window
, ни к каким-либо из моих локальных переменных через замыкание.
Точно так же, как слово для мудрых, мне все еще приходится выполнять статические проверки кода для пользовательского кода, чтобы убедиться, что они не используют другие хитрые способы доступа к глобальной области видимости. Например, следующий определенный пользователем код получает прямой доступ к window
:
test = function() {
return this.window
};
return test();