Установить функцию по умолчанию это значение - PullRequest
2 голосов
/ 27 апреля 2020

Справочная информация:

Я запускаю изолированную рамку iframe, которая имеет только разрешение "allow-scripts". В песочнице загружается скрипт с пользовательским js, предоставленным пользователем. Теперь я хочу управлять доступом к глобальным функциям / объектам, таким как XMLHttpRequest. В настоящее время я достигаю этого с помощью следующего кода:

const CLEARED_WINDOW_SCOPE= {};
const scope = { /* Here goes the globals the script should have access too */};
const propertyNames = Object.getOwnPropertyNames(window);

for(let property of propertyNames){
    CLEARED_WINDOW_SCOPE[property] = undefined;
}

with(CLEARED_WINDOW_SCOPE){
    with(scope){
        (function (window, self, frames, globalThis){
            ${scriptContent}
        }).call(scope, scope, scope, scope, scope); 
    }
}

Сценарий выполняет следующие действия:

  1. Создание объекта со всеми именами свойств окна, для которых установлено значение undefined
  2. Создать объект со всеми свойствами, к которым у пользователя тоже должен быть доступ
  3. Оберните код пользователя двумя операторами with, первый очищает все глобальные переменные, второй предоставляет доступ к определенным
  4. Оберните пользовательский код с помощью функция, которая вызывается с scope как this значение

Пока все работает отлично, как и ожидалось.

Проблема:

Основная проблема, с которой я столкнулся сейчас, заключается в том, что когда пользователь определяет такую ​​функцию:

function aFunction(){
   console.log(this);
}

Он получает доступ к обычному объекту окна, поскольку значение по умолчанию this в функции - это window.

Вопрос:

Возможно ли как-то изменить значение функции this по умолчанию на значение this окружающей области видимости. Поскольку пользователь создает скрипт, я не могу обернуть все вызовы функций с помощью aFunction.bind(scope). Или есть какое-либо другое значение, предотвращающее доступ к объекту глобального окна?

1 Ответ

3 голосов
/ 27 апреля 2020

Можно ли каким-то образом изменить значение по умолчанию для функции этой функции на значение this из окружающей области.

Нет, но вы можете сделать следующую лучшую (?) Вещь : установка undefined. Просто принудительный строгий режим:

"use strict";

// User's code
(function (){
  console.log(this)
})();

Кроме того, я не эксперт по безопасности JavaScript, но песочница JS - действительно сложная проблема c из-за таких вещей, как загрязнение прототипа.

Редактировать: Как отмечается в комментариях CherryDT , этот метод не является полностью безопасным. Пользователи по-прежнему могут получить доступ к <iframe> window, например, создав функцию с конструктором Function. Кроме того, ссылку на основной window можно получить через <iframe> window (window.parent).

Возможно, будет правильным использовать это решение для предоставленный пользователем код (поскольку пользователи могут просто открыть консоль DevTools и начать печатать), но убедитесь, что код поступает от пользователя , а не от параметра поиска URL, например. Если код полностью не доверяет, я бы рекомендовал использовать хорошо известную библиотеку, такую ​​как Google Caja .

...