Безопасная песочница и выполнение представленного пользователем 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. Вы можете найти здесь некоторую информацию.