Песочницы и safeRequire

Sandbox в Node.js — изолированный VM-контекст с подменённым require. Фреймворк отдаёт компоненту только разрешённое API, всё остальное недоступно.

Что это / Зачем

  • Безопасность: код плагина/приложения не может тянуть произвольные модули.
  • Гибкость: фреймворк подменяет реализации (логгер, fs, db) для разных окружений.
  • Горячая перезагрузка: можно подменять модули в работающем процессе без рестарта.
  • Декларативные зависимости через JSON.

Признаки правильной изоляции

  • Прямой require из песочницы недоступен.
  • Все библиотеки — через namespace api.fs, api.log и т.д.
  • Каждая песочница имеет свой context.global.
  • Между песочницами нет общих ссылок (иначе утечка).

Пример: создание песочницы

const vm = require('vm');
const api = { fs: require('./sandbox.fs'), log: console.log };
const sandbox = { api, console };
const context = vm.createContext(sandbox);
context.global = context; // привычное global внутри
const script = new vm.Script(src);
script.runInContext(sandbox);

Антипаттерн: общий require

// БЕЗ песочницы: компонент достаёт что угодно, ломает изоляцию
require('fs').unlinkSync('/etc/passwd');     // никто не остановил
require('child_process').exec('rm -rf /');   // ничего не помешает

Утечка между песочницами

// Если api общий и кто-то делает api.console.log = () => {},
// это сломает логирование во ВСЕХ песочницах.
// Решение: для каждой песочницы клонировать api через bind/proxy.

🎓 Источники

  • 🎓 [Inversion of Control and Dependency Injection in Node.js] · 2018-10-09 · YouTube
    • FS Sandboxing — перехват вызовов fs, изоляция в каталоге.
    • createContext устарел — нужно new vm.Script(src).runInNewContext(sandbox).
  • 🎓 [Модули, слои, структура проекта, песочницы] · 2018-10-02 · YouTube
    • Принудительное экранирование модулей.
  • 🎓 [9. Летняя школа 2017 — Песочницы, IoC, DI] · 2019-11-30 · YouTube
    • safeRequire и runSandboxed — main как точка входа.

См. также