Безопасная песочница и выполнение представленного пользователем JavaScript?

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

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

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

РЕДАКТИРОВАТЬ: Я собираюсь пойти дальше и обновить с тем, что я нашел. Это модуль Sandcastle (bcoe/sandcastleКажется, я делаю то, что имею в виду. Не уверен, насколько это безопасно, но, поскольку я не для этого слишком важен, я думаю, что если я попробую. Я добавлю свой ответ, если смогу успешно это сделать.

4 ответа

Решение

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

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

Вы можете использовать поддержку песочницы в nodejs с vm.runInContext('js code', context), пример в документации API:

https://nodejs.org/api/vm.html

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

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

$ npm install vm2

затем:

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

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

как уже упоминалось в комментариях других ответов.

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

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

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

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

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

Другие вопросы по тегам