nodeJS Быстрый веб-сервер на javascript движке V8

22Мар/101

Безопасное выполнение стороннего кода в Node.js

Итак, следующий пункт после game loop — система скриптов. Понятное дело, это будет JavaScript. Но я хочу добиться большего — чтобы можно было исполнять сторонний код без боязни уронить всё приложение.

Вообще говоря Node падает довольно легко. Любая синтаксическая ошибка (в том числе в подключаемом модуле) или обращение к несуществующему методу — и всё, game over. Этого я и хочу избежать. Можно будет, например, сделать игру наподобие Habrawars (или даже на её основе), но проводящую бои между роботами участников автоматически, раз в час например. В HabraWars мне этого очень не хватало :)

Для безопасного выполнения кода у нас не так много вариантов. Eval, Evalcx, дочерний процесс.

  • Eval. Именно этим путём пошёл создатель Habrawars. Код выполняется в контролируемом окружении, ошибки в коде легко ловить. Минусы — коду доступен глобальный контекст, его конечно можно изолировать, но не то чтобы это было просто. В Habrawars например был не закрыт (и сейчас не закрыт, я полагаю) console.log — мелочь конечно, но можно пропустить и что нибудь посерьёзнее.
  • Evalcx. Улучшенная версия eval, позволяющая задавать произвольный контекст выполняемому коду. Пришла в Node.js прямиком из Spidermonkey.
  • Дочерний процесс. Ничего не мешает нам запустить дочерний экземпляр node с нужным скриптом. Плюс: мы можем прибить дочерний процесс, если вдруг он решит войти в бесконечный цикл. Минус: дочернему процессу доступно очень много функций, в том числе запись в файлы и обращение в сеть. Впрочем, можно ограничить если не его функциональность, то хотя бы максимальный возможный ущерб — например, запустив его под пользователем с урезанными правами.

Т.к. eval, вообще говоря, выполняется в глобальном контексте и код внутри него имеет доступ к разным интересным штукам вплоть до сети и файловой системы, рассмотрим два оставшихся варианта по очереди. Давайте возьмём pulse.js из предыдущего примера, и используем интервальный таймер для организации game loop. Теперь нам надо создать NPC, который будет загружаться из другого файла (и не ронять основной цикл Pulse в случае ошибки в файле).

Метки записи: Читать полностью