Подтвердить что ты не робот

Безопасная песочница и выполнить пользовательский JavaScript?

Я хотел бы иметь возможность позволить пользователям отправлять произвольный код JavaScript, который затем отправляется на сервер Node.JS и безопасно выполняется до того, как вывод будет отправлен обратно нескольким клиентам (как JSON). Функция eval приходит на ум, но я знаю, что это связано с несколькими проблемами безопасности (пользовательский код будет иметь доступ к Node File API и т.д.). Я видел некоторые проекты, такие как Microsoft Web Sandbox и Google Caja, которые позволяют выполнять дезинфицированную разметку и script (для встраивания сторонних объявлений на веб-сайты), но похоже, что это инструменты на стороне клиента, и я не уверен, что их можно безопасно использовать в Node.

Есть ли стандартный способ для песочницы и запускать ненадежный JavaScript в Node, получая вывод. Ошибочно ли пытаться сделать это на стороне сервера?

РЕДАКТИРОВАТЬ: Не важно, чтобы пользователь мог использовать все возможности JavaScript, на самом деле было бы предпочтительнее иметь возможность выбирать, какие API-интерфейсы будут предоставляться коду пользователя.

EDIT: Я собираюсь продолжить и обновить то, что нашел. Этот модуль Sandcastle ( bcoe/sandcastle), похоже, нацелен на то, что я имею в виду. Не уверен, насколько это безопасно, но поскольку я не для чего-то слишком важного, я думаю, что попробую. Я добавлю свой собственный ответ, если мне удастся это сделать.

4b9b3361

Ответ 1

Этот ответ устарел, поскольку gf3 не обеспечивает защиту от взлома песочницы

http://gf3.github.io/sandbox/ - вместо require('vm') используется require('child_process').

Ответ 2

Вы можете использовать поддержку песочницы в 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", оно кажется ошибочным. Пожалуйста, посмотрите на комментарии.

Ответ 3

В Node.js вы можете создать дочерний процесс с песочницей, но вам также нужно добавить код с помощью "use strict";, в противном случае можно разбить песочницу с помощью arguments.callee.caller.

Не уверен, почему вам нужно отправить его на сервер, потому что этот код также может быть выполнен в изолированном веб-работнике.

Также ознакомьтесь с моей библиотекой Jailed, которая упрощает все, что только что упоминалось для Node.js и веб-браузера, и дополнительно предоставляет возможность экспортировать набор функций в песочницу.

Ответ 4

Одним из вариантов было бы использовать http://github.com/patriksimek/vm2:

$ npm install vm2

то

const {VM} = require('vm2');
const vm = new VM();

vm.run(`1 + 1`);  // => 2

как указано в комментариях других ответов.

Я не знаю, насколько это безопасно, но, по крайней мере, утверждает, что он безопасно работает с ненадежным кодом (в README). И я не мог найти каких-либо очевидных проблем безопасности, поскольку решения, предлагаемые в других ответах здесь.

Ответ 5

В зависимости от вашего использования, я бы посоветовал вам также рассмотреть возможность защиты своей песочницы с помощью виртуальной среды, такой как gVisor. Вы можете найти некоторую информацию здесь.