Подтвердить что ты не робот

Как я могу передать ненадежный пользовательский контент JavaScript-песочницы?

Мне нужно обслуживать созданные пользователем сценарии на моем сайте (вроде jsfiddle). Я хочу, чтобы скрипты запускались в браузерах посетителей безопасным образом, изолированным от страницы, на которой они были отправлены. Поскольку код отправляется пользователями, нет гарантии, что он заслуживает доверия.

Сейчас я могу представить три варианта:

  • Подавать контент, отправленный пользователем в iframe из другого домена, и полагаться на политику одного и того же происхождения. Это потребует установки дополнительного домена, который я бы хотел избежать, если это возможно. Я считаю, что это так, как это делает jsfiddle. script может по-прежнему наносить некоторый урон, изменяя, например, top.location.href, что меньше идеала. http://jsfiddle.net/PzkUw/
  • Используйте атрибут sandbox. Я подозреваю, что это плохо поддерживается в браузерах.
  • Санируйте скрипты перед их обслуживанием. Я бы предпочел не идти туда.

Есть ли другие решения или рекомендации по вышеуказанному?

Обновление

Если, как я подозреваю, первый вариант - лучшее решение, , что может сделать вредоносное script, кроме изменения местоположения верхнего окна, и как я могу предотвратить это? Я могу манипулировать или отклонять определенные сценарии на основе анализа статического кода, но это hard, учитывая количество способов доступа к объектам и сложность анализа javascript в целом статически. По крайней мере, для этого потребуется полномасштабный парсер и ряд сложных правил (некоторые, но я подозреваю не все, из которых присутствуют в JSLint).

4b9b3361

Ответ 1

Создайте хорошо определенный интерфейс сообщений и используйте JavaScript Web Worker для кода, который вы хотите изолировать. Веб-работники HTML5

Работники Web не имеют доступа к следующим объектам DOM.

  • Объект window

  • Объект документа

  • Родительский объект

Таким образом, они не могут перенаправить вашу страницу или изменить данные на ней.

Вы можете создать шаблон и четко определенный интерфейс обмена сообщениями, чтобы пользователи могли создавать сценарии веб-рабочих, но ваш script имел бы последнее слово в отношении того, что получает управление.

EDIT Комментарий Джордана Грея, подключающего библиотеку JavaScript, которая, похоже, делает то, что я описал выше. https://github.com/eligrey/jsandbox

Ответ 2

Некоторые идеи инструментов, которые могут быть полезны в вашем приложении, - они атакуют проблему с двух разных направлений: Caja компилирует ненадежный код JavaScript в безопасное, в то время как AdSafe определяет подмножество JavaScript, который безопасен в использовании.

Каха

Caja

Компилятор Caja - это инструмент для безопасного встраивания стороннего HTML, CSS и JavaScript в ваш сайт. Он обеспечивает богатое взаимодействие между страницей внедрения и встроенными приложениями. Caja использует модель безопасности объектов, позволяющую использовать широкий диапазон гибких политик безопасности, чтобы ваш сайт мог эффективно контролировать то, что встроенный сторонний код может выполнять с пользовательскими данными.

AdSafe

AdSafe

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

Ответ 3

Как уже упоминалось, атрибут sandbox iframe уже поддерживается основными браузерами, но я бы дополнительно предложил смешанное решение: запустить веб-рабочего внутри изолированного iframe. Это даст отдельный поток и защитит событие изолированным iframe DOM от ненадежного кода. Так работает моя библиотека Jailed. Кроме того, вы можете обойти любые ограничения, экспортировав любой набор функций в песочницу.

Ответ 4

Если вы хотите изолировать какой-либо фрагмент кода, удалив его для доступа к окну, документу и родительскому элементу, вы могли бы его достичь, обернув его в закрытие, где это локальные пустые переменные:

(function(window, document, parent /* Whatever you want to remove */){
  console.log(this);      // Empty object
  console.log(window);    // undefined
  console.log(document);  // undefined
  console.log(parent);    // undefined
}).call({});

Вызов его с пустым объектом важен, поскольку в противном случае это укажет на объект окна