Ответ 1
Этот ответ устарел, поскольку gf3 не обеспечивает защиту от взлома песочницы
http://gf3.github.io/sandbox/ - вместо require('vm')
используется require('child_process')
.
Я хотел бы иметь возможность позволить пользователям отправлять произвольный код JavaScript, который затем отправляется на сервер Node.JS и безопасно выполняется до того, как вывод будет отправлен обратно нескольким клиентам (как JSON). Функция eval
приходит на ум, но я знаю, что это связано с несколькими проблемами безопасности (пользовательский код будет иметь доступ к Node File API и т.д.). Я видел некоторые проекты, такие как Microsoft Web Sandbox и Google Caja, которые позволяют выполнять дезинфицированную разметку и script (для встраивания сторонних объявлений на веб-сайты), но похоже, что это инструменты на стороне клиента, и я не уверен, что их можно безопасно использовать в Node.
Есть ли стандартный способ для песочницы и запускать ненадежный JavaScript в Node, получая вывод. Ошибочно ли пытаться сделать это на стороне сервера?
РЕДАКТИРОВАТЬ: Не важно, чтобы пользователь мог использовать все возможности JavaScript, на самом деле было бы предпочтительнее иметь возможность выбирать, какие API-интерфейсы будут предоставляться коду пользователя.
EDIT: Я собираюсь продолжить и обновить то, что нашел. Этот модуль Sandcastle ( bcoe/sandcastle
), похоже, нацелен на то, что я имею в виду. Не уверен, насколько это безопасно, но поскольку я не для чего-то слишком важного, я думаю, что попробую. Я добавлю свой собственный ответ, если мне удастся это сделать.
Этот ответ устарел, поскольку gf3 не обеспечивает защиту от взлома песочницы
http://gf3.github.io/sandbox/ - вместо require('vm')
используется require('child_process')
.
Вы можете использовать поддержку песочницы в nodejs с vm.runInContext('js code', context), пример в документации API:
https://nodejs.org/api/vm.html#vm_vm_runinthiscontext_code_options
const util = require('util');
const vm = require('vm');
const sandbox = { globalVar: 1 };
vm.createContext(sandbox);
for (var i = 0; i < 10; ++i) {
vm.runInContext('globalVar *= 2;', sandbox);
}
console.log(util.inspect(sandbox));
// { globalVar: 1024 }
ПРЕДУПРЕЖДЕНИЕ: как указано "s4y", оно кажется ошибочным. Пожалуйста, посмотрите на комментарии.
В Node.js вы можете создать дочерний процесс с песочницей, но вам также нужно добавить код с помощью "use strict";
, в противном случае можно разбить песочницу с помощью arguments.callee.caller
.
Не уверен, почему вам нужно отправить его на сервер, потому что этот код также может быть выполнен в изолированном веб-работнике.
Также ознакомьтесь с моей библиотекой Jailed, которая упрощает все, что только что упоминалось для Node.js и веб-браузера, и дополнительно предоставляет возможность экспортировать набор функций в песочницу.
Одним из вариантов было бы использовать http://github.com/patriksimek/vm2:
$ npm install vm2
то
const {VM} = require('vm2');
const vm = new VM();
vm.run(`1 + 1`); // => 2
как указано в комментариях других ответов.
Я не знаю, насколько это безопасно, но, по крайней мере, утверждает, что он безопасно работает с ненадежным кодом (в README). И я не мог найти каких-либо очевидных проблем безопасности, поскольку решения, предлагаемые в других ответах здесь.
В зависимости от вашего использования, я бы посоветовал вам также рассмотреть возможность защиты своей песочницы с помощью виртуальной среды, такой как gVisor. Вы можете найти некоторую информацию здесь.