2013-07-07 6 views
34

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

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

EDIT: Не важно, чтобы пользователь мог использовать все возможности JavaScript, на самом деле было бы предпочтительнее выбирать и выбирать, какие API-интерфейсы будут предоставляться коду пользователя.

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

+0

Почему он должен выполняться на вашем сервере, а не на клиенте? – delnan

+2

Я думаю, что это ошибка, но вы можете попробовать материал «vm» для узла - http: //nodejs.org/api/vm.html – JoshRagem

+1

Это для концепции игровой концепции для удовольствия, я не могу доверять клиентов для выполнения кода. Я хочу сделать это на стороне сервера по этой причине и потому, что вывод будет сериализован и отправлен одному или нескольким другим клиентам. Похоже, что модуль vm или что-то обертывание - это то, что я хочу. –

ответ

3

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

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

+0

Я собираюсь пойти и принять, я буду рассматривать как песочницу, так и модуль sandcastle, с которым я связан выше в течение следующих нескольких дней. Благодарю. –

+1

Не вводите в заблуждение, gf3/sandbox использует как дочерний процесс, так и модули vm, проверьте код. И все решения для песочницы делают то же самое. –

+5

Для будущих зрителей, в настоящее время с его помощью gf3 можно использовать и может быть разбит. –

4

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

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

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

+2

В это время взломанный взломан : https://github.com/asvd/jailed/issues/33 – arve0

+0

@ arve0 вы правы, тюрьма была скомпрометирована под узлом, исправление готовится – asvd

+2

Альтернатива: https://github.com/patriksimek/vm2 Похоже на то, что быть в безопасности, но, выбирая лог-потенциал, я буду осторожен. – arve0

9

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

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 } 

WARN: Как указано на "s4y" его кажется, устранены. Посмотрите комментарии.

+1

Это не кажется безопасным, например: 'vm.runInNewContext ('this.constructor.constructor (" return process ")(). Exit()');' (из vm2 README: https: // github .com/patriksimek/Vm2). – s4y

2

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

$ npm install vm2 

затем:

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

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

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

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