Песочницы и VM в Node
Модуль
vmпозволяет компилировать и исполнять JavaScript в изолированном контексте — для плагинов, hot reload, sandbox-режимов и FaaS.
Суть
Каждый Node.js процесс делит один глобальный объект между модулями. Чтобы запустить ненадёжный/перезагружаемый код изолированно, используется vm.createContext — он создаёт отдельный JS-контекст со своим global, своими таймерами и своим API. Это НЕ безопасный sandbox от вредоносного кода (для этого нужны worker_threads/процессы), но полезно для:
- горячей перезагрузки модулей (Metarhia: application code в vm)
- DI: инжектируем нужное API внутрь контекста, остальное недоступно
- перехвата
console.log/process.exitв подсистемах - ограничения времени выполнения через
timeout
Пример
const vm = require('vm');
const sandbox = {
console,
require: (id) => id === 'fs' ? require('fs') : null, // только fs разрешён
result: null,
};
vm.createContext(sandbox);
const code = `
const fs = require('fs');
result = fs.readFileSync('./data.txt', 'utf8');
`;
vm.runInContext(code, sandbox, { timeout: 1000 });
console.log(sandbox.result);
Что важно
runInNewContext— каждый раз создаёт новый context (дорого, но изоляция полная)runInContext— переиспользует уже созданный (быстрее)runInThisContext— исполнить в текущем context (только timeout, без изоляции глобала)new vm.Script(code).runInContext(ctx)— скомпилировать раз, исполнять много разtimeout— kill при превышении (но не от async-кода)
Подводные камни
- Это не security boundary — код в vm может
require('process').exitесли ему датьrequire - Объекты из основного контекста, переданные в sandbox, остаются доступны → утечка ссылок
- Перезагрузка кода через
delete require.cache[...]+vm.runInContext— хак, не пользоваться без необходимости - Для настоящей изоляции — worker_threads, child_process или Deno permissions
🎓 Источники
- 🎓 [Модули, слои, структура проекта, песочницы] · 2018-10-02 · YouTube · [Marp](../../../Documents/TimurShemsedinov/2018-10-02 — Модули, слои, структура проекта, песочницы в JavaScript и Node.js (O7A9chb573E).md)
- Тезисы: создание контекста, обёртка require внутри песочницы, рекурсивная
context.global, инжект API, защита парсинга таймаутом, чтениеexportsиз песочницы, framework запускает application через vm - Цитата: «fs заблокирован, net доступен — мы решаем что доступно из application»
- Тезисы: создание контекста, обёртка require внутри песочницы, рекурсивная
- 🎓 [Логирование на Node.js] · 2019-04-25 · YouTube
- Тезисы: перехват
console.logчерез VM-песочницу, прозрачная подмена для приложения
- Тезисы: перехват
- 🎓 [Песочницы, IoC, DI, IPC (Летняя школа 2017)] · 2019-11-30 · YouTube
- Тезисы: песочницы как механизм IoC/DI, перезагрузка приложения без рестарта процесса
- 🎓 [Serverless Clouds (FaaS) и изоляция контекстов запросов] · 2019-12-05 · YouTube
- Тезисы: vm как лёгкая FaaS-альтернатива контейнерам, изоляция per-request