В ноде есть встроенный механизм песочницы для запуска опасного кода.
Но вот ещё про одну забавную проблему расскажу.
Как можно подвесить процесс через песочницу? Очень просто:
Но вы скажете, что есть же параметр timeout:
Уже лучше. Но проблема в том, что timeout не ловит микротаски. Выносим луп в микротаску и снова DoS
Ок, проблема известная, в 15-й ноде дырку заделали фанерой.
Почему такое апи? Ума не приложу :) Но в этом режиме песочница разматывает микротаски сразу после макротасок и таймаут общий. Почти хорошо стало, но что если мы решили передать в песочницу что-нибудь асинхронное? И пользователь сможет выйти на следующий луп. Тогда ой:
Всё попало, шеф. У нас DoS.
В общем, посмотрите лучше на vm2 или на более интересную изоляцию через isolated-vm
vm.runInNewContext(<код>, <контекст>)
и погнали. Лучше и безопаснее eval
, но... со своими проблемами. Всё ещё можно вылезти из песочницы и ударить в глобал. this.constructor.constructor
и побежали веселиться. Но вот ещё про одну забавную проблему расскажу.
Как можно подвесить процесс через песочницу? Очень просто:
vm.runInNewContext('while(true){}',{});
Но вы скажете, что есть же параметр timeout:
vm.runInNewContext('while(true){}',{timeout: 5});
Уже лучше. Но проблема в том, что timeout не ловит микротаски. Выносим луп в микротаску и снова DoS
vm.runInNewContext(
'Promise.resolve().then(()=>{while(true) {}});',
{},
{timeout:5}
);
Ок, проблема известная, в 15-й ноде дырку заделали фанерой.
vm.runInNewContext(
'Promise.resolve().then(()=>{while(true) {}});',
{},
{timeout:5, microtaskMode: 'afterEvaluate'}
);
Почему такое апи? Ума не приложу :) Но в этом режиме песочница разматывает микротаски сразу после макротасок и таймаут общий. Почти хорошо стало, но что если мы решили передать в песочницу что-нибудь асинхронное? И пользователь сможет выйти на следующий луп. Тогда ой:
vm.runInNewContext(
`
setTimeout(() => {
while(true) {};
}, 10000);`,
{setTimeout},
{timeout:5, microtaskMode: 'afterEvaluate'}
);
Всё попало, шеф. У нас DoS.
В общем, посмотрите лучше на vm2 или на более интересную изоляцию через isolated-vm