
Изолированная JavaScript-песочница для Node.js, которая выполняет недоверенный код с ограниченным доступом к встроенным модулям и ресурсам хоста посредством перехвата на основе Proxy.
vm2 — это песочница, которая может запускать недоверенный код с использованием разрешённых встроенных модулей Node.
npm install vm2
## Quick Examples```js
import { VM } from 'vm2';
const vm = new VM();
vm.run(`process.exit()`); // TypeError: process.exit is not a function
I need the actual content of chunk 5 to translate it. Please provide the Markdown text you want translated.```js import { NodeVM } from 'vm2';
const vm = new NodeVM({ require: { external: true, root: './', }, });
vm.run(
var request = require('request'); request('http://www.google.com', function (error, response, body) { console.error(error); if (!error && response.statusCode == 200) { console.log(body); // Show the HTML for the Google homepage. } });,
'vm.js',
);
## Важное предупреждение о безопасности
**Прежде чем использовать vm2, вы должны понимать, как он работает и каковы его ограничения.**
vm2 пытается изолировать недоверенный JavaScript-код **в том же процессе Node.js**, что и ваше приложение. Это достигается за счёт сложной сети [Proxy](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Proxy), которые перехватывают и опосредуют каждое взаимодействие между песочницей и хост-средой.
### Фундаментальная проблема
JavaScript — чрезвычайно динамичный язык. Доступ к объектам можно получить через цепочки прототипов, до конструкторов можно добраться через объекты ошибок, символы предоставляют протокольные хуки, а асинхронное выполнение создаёт временные окна. Огромное количество способов перехода от одного объекта к другому в JavaScript делает создание герметичной внутрипроцессной песочницы крайне сложной задачей.
**Мы честны в отношении этой реальности:** несмотря на все наши усилия, исследователи и специалисты по безопасности постоянно обнаруживают новые способы обхода песочницы vm2. Мы активно исправляем эти уязвимости по мере их поступления, но природа «кошки-мышки» внутрипроцессной изоляции означает, что:
1. **В будущем, скорее всего, будут обнаружены новые обходы.** Проверьте наши [бюллетени безопасности](https://github.com/patriksimek/vm2/security/advisories) на предмет известных уязвимостей.
2. **Вы должны поддерживать vm2 в актуальном состоянии**, чтобы получать последние исправления безопасности. Подпишитесь на бюллетени безопасности и своевременно обновляйтесь.
3. **vm2 не должен быть вашей единственной линией обороны.** Эшелонированная защита необходима при запуске недоверенного кода.
### Более надёжные альтернативы
Если вам требуются более строгие гарантии изоляции, рассмотрите следующие альтернативы, обеспечивающие **настоящую изоляцию на уровне процесса или оборудования**:
| Решение | Подход | Производительность | Компромиссы |
|----------|----------|-------------|------------|
| **[isolated-vm](https://github.com/laverdet/isolated-vm)** | Отдельные изоляты V8 (отдельная куча V8) | Высокая | В режиме сопровождения; требует ручного обновления V8 |
| **Отдельный процесс / Worker** | `child_process` или Worker-потоки с ограниченными правами | Средняя | Более высокие накладные расходы на IPC; данные должны быть сериализованы |
| **Контейнеры / ВМ** | Docker, gVisor, Firecracker | Низкая | Накладные расходы на запуск; ресурсоёмкость |
| **Управляемые сервисы** | Облачное выполнение кода (например, AWS Lambda, Cloudflare Workers) | Переменная | Сетевая задержка; внешняя зависимость |
### Когда vm2 всё ещё может быть уместен
vm2 может подходить, когда:
- Вам нужна тесная интеграция с объектами хоста и быстрое синхронное взаимодействие
- Недоверенный код поступает из относительно надёжного источника (например, внутренние инструменты, плагинные системы с проверенными авторами)
- Вы комбинируете vm2 с другими уровнями безопасности (сетевая изоляция, ограничения файловой системы, лимиты ресурсов)
- Вы принимаете риск и активно отслеживаете обновления безопасности
**Если вы запускаете код из полностью недоверенных источников (например, произвольные пользовательские отправки), мы настоятельно рекомендуем использовать решение с более строгими гарантиями изоляции.**
## Среды выполнения
| Среда | Статус |
|---------|--------|
| Node.js | Поддерживается. Песочница является границей безопасности. |
| Bun | **Экспериментально.** Частичная функциональная совместимость — **не** является границей безопасности. |
К Bun применяются два отдельных ограничения, и ни одно из них не подразумевает другое.
**Это не граница безопасности.** Модель угроз vm2, каталог атак в
[`docs/ATTACKS.md`](https://github.com/patriksimek/vm2/blob/main/docs/ATTACKS.md) и каждый регрессионный тест в `test/ghsa/`
основаны на внутренностях V8. JavaScriptCore, который использует Bun, имеет свои
собственные аналоги, и ни один из них не был проверен на соответствие мосту vm2. Прохождение
набора тестов под Bun демонстрирует совместимость, а не то, что песочница там удерживается. **Не
используйте vm2 на Bun для изоляции недоверенного кода.**
**Совместимость частичная, а не полная.** Зелёный прогон Bun охватывает только те тесты,
которые фактически выполняются там. `test/bun-skips.js` перечисляет, что исключено и почему,
а известные поведенческие пробелы включают:
- `Buffer.from(arrayLike)` возвращает буфер нулевой длины
- Метаданные `VMScript` `filename` / `lineOffset` / `columnOffset` не
наблюдаемы, поскольку объекты CallSite в JSC не содержат методов
- `Object.freeze` на замороженном объекте хоста с неконфигурируемым аксессором
выбрасывает `TypeError` нарушения инварианта прокси там, где V8 этого не делает
- некоторые операции `Buffer` через границу песочницы выполняются значительно медленнее —
`allocUnsafe` на 64 МБ занимает более 400 секунд против 1,7 на Node, что достаточно медленно,
чтобы восприниматься как зависание
Относитесь к поддержке Bun как к совместимости «наилучшим образом» для доверенного кода и проверяйте
список исключений, прежде чем полагаться на какое-либо конкретное поведение.
## Возможности
- Безопасно выполняет недоверенный код в одном процессе рядом с вашим кодом
- Полный контроль над выводом консоли песочницы
- Песочница имеет ограниченный доступ к методам процесса
- Есть возможность подключать модули (встроенные и внешние) из песочницы
- Можно ограничить доступ к определённым (или всем) встроенным модулям
- Можно безопасно вызывать методы и обмениваться данными и обратными вызовами между песочницами
- Активно поддерживается с исправлениями известных методов обхода (см. [Предупреждение о безопасности](#important-security-disclaimer))
- Поддержка транспилятора
## Как это работает
- Использует внутренний модуль VM для создания безопасного контекста.
- Использует [Proxy](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Proxy) для предотвращения выхода из песочницы.
- Переопределяет встроенный require для контроля доступа к модулям.
Для подробного изучения внутренностей vm2 см. [docs/ATTACKS.md](https://github.com/patriksimek/vm2/blob/main/docs/ATTACKS.md).
## В чём разница между vm из Node и vm2?
Попробуйте сами:```js
import { runInNewContext } from "node:vm";