Комментарии 29
как я написал свой eval()
В статье:
я запустил eval() в Worker
«Мы сделали eval() на других технологиях, он работает почти так же, как тот же eval(), который у нас уже есть. Фактически у меня в коде есть функция eval(), но реализованная с помощью Workers, оператора with и Proxy.»
В общем мой комментарий о том, что я ожидал рассказ о парсерах/компиляторах/синтаксических деревьях, а получил eval посредством Worker.
eval() в Worker
не соглашусь, это именно запуск кода в другом потоке. eval() это же про рантайм выполнение кода, а тут все уже сгенерировано до запуска воркера.
Отличный рассказ!
Кстати, видел уже такую идею про вебворкеры здесь https://github.com/asvd/jailed
const getRandomString = _ => Math.random().toString(36).substr(2);
window[getRandomString()]("Pwned!");
//есть вероятность, что будет вызван alert
этот код тоже потенциально вызовет alert()
(new Function(`${getRandomString()}("Pwned!")`))()
нет, числа не запрещать не надо, но можно запретить обращение ко всяким свойствам вроде ._proto_, .constructor и т.д, то есть составить белый список того что мы хотим разрешить — вроде базовых типов, выражений, операторов условий и циклов, и дальше в зависимости от того нужны ли другие возможности js можно также добавить конструкции и методы для создания и работы с объектами, массивами и если нужно также базовый апи Math. Date.. А инструменты статической типизации (typescript или flow) могут вообще протипизировать а мы соотвественно провалидировать еще больше фич js и если где-то встречается "any" или работа с типом который не находится в белом списке то не разрешать этому коду выполниться.
В любом случае анализ через ast это единственный надежный способ потому что все остальные способы пытаются предоставить все возможности js и убрать опасные а это очень ненадежно, на nodejs есть похожая история с попыткой сделать песочницу через vm-модуль (тут и тут) и можно только удивляться какие хаки можно придумать с этим js
Я понимаю желание поразбирать алгоритмы парсинга деревьев (сам такой), но выходит вопрос о времени, которое уйдет на эту задачу, будет ли игра после этого?
Суть в том, что статическая анализация динамического ЯП обладает большим количеством проблем, нежели песочница. Вывод следующий — а что из этих двух путей тогда вообще костыль?
Распарсите вы код, а он обфусцирован. Как валидировать будете?
Статья по теме: Почему анализ защищенности JavaScript нельзя по-настоящему автоматизировать?
Или сделать специальный PRO уровень сложности в ним ещё можно.
Через прототип в JS можно вытащить практически всё. Удивительно, но все эти методы все равно доступны через прототип.можно пример, как можно вытащить всё через прототип, и как удаление свойств (как на слайде) это предотвратит? я, кстати, не уверен, что delete удалит все свойства, по крайней мере на странице несколько свойств выживают.
А почему было приятно решение выполнять код на клиенте?
Для мультиплеера вроде общепринятый подход прокинуть действия игрока на сервер, на сервере посчитать логику, на клиент вернуть результаты в виде, по сути, обновления графики.
И при такой архитектуре можно было бы реализовать некостыльный подход: на сервер запихнуть реальную песочницу, с ограничениями времени/памяти/стека и без лишних объектов по умолчанию, типа всяких window, чтобы не пришлось их выпиливать.
Было мало времени, я рассчитывал сделать песочницу с доступом к стейту боя, чтобы можно было ставить условия от текущей ситуации на поле, но в итоге понял что не успеваю и сделал защищённую песочницу в браузере. Вообще архитектура расчетов на сервере для онлайн игры единственно верная, думаю, что в дальнейшем буду отталкиваться от нее, если вдруг не увижу нового отличного способа запустить код из строки в браузере)
JS-битва: как я написал свой eval()