Bezpiecznie sandbox i wykonać użytkownika przesłane JavaScript?

Chciałbym mieć możliwość pozwalania użytkownikom przesyłać dowolny kod JavaScript, który jest następnie wysyłany do węzła.Js server i bezpiecznie wykonywane przed wysłaniem wyjścia z powrotem do wielu klientów (jako JSON). Funkcja eval przychodzi mi na myśl, ale wiem, że ma to wiele problemów związanych z bezpieczeństwem (kod przesłany przez użytkownika byłby w stanie uzyskać dostęp do API plików Node, itp.). Widziałem kilka projektów takich jak Microsoft Web Sandbox i Google Caja które pozwalają na wykonanie sanitized markup i script (dla osadzanie reklam innych firm na stronach internetowych), ale wydaje się, że są to narzędzia po stronie klienta i nie jestem pewien, czy można je bezpiecznie używać w Node.

Czy istnieje standardowy sposób na piaskownicę i wykonanie nie zaufanego JavaScript w węźle, uzyskanie wyjścia. Czy to błąd próbować zrobić to po stronie serwera?

EDIT: nie jest ważne, aby użytkownik mógł wykorzystać pełne możliwości JavaScript, w rzeczywistości lepiej byłoby wybrać i wybrać, które API byłyby podane do kodu użytkownika.

EDIT: zamierzam zaktualizować to, co znalazłem. Moduł Zamek z piasku (bcoe/sandcastle) wydaje się, że chce zrobić to, co mam na myśli. Nie wiem, jak jest bezpieczny, ale ponieważ nie jest to zbyt ważne, myślę, że spróbuję. Dodam własną odpowiedź, jeśli uda mi się to zrobić.

Author: Cory Gross, 2013-07-07

4 answers

Ta odpowiedź jest przestarzała, ponieważ gf3 nie zapewnia ochrony przed łamaniem piaskownicy

Http://gf3.github.io/sandbox / - używa require('child_process') zamiast require('vm').

 4
Author: Ginden,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-12 16:43:18

Możesz używać sandboxa w nodejs z maszyną wirtualną.runInContext ('kod js', kontekst), przykład w dokumentacji 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 }

WARN: jak wskazuje "s4y" wydaje się być wadliwy. Proszę spojrzeć na komentarze.

 10
Author: ton,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-17 13:02:46

Pod Węzłem.js możesz utworzyć sandboxed proces potomny, ale musisz również dołączyć kod za pomocą "use strict";, w przeciwnym razie można złamać sandbox za pomocą arguments.callee.caller.

Nie wiem, dlaczego musisz wysłać go na serwer, ponieważ kod może być również wykonywany w piaskownicy web-workera.

Spójrz także na moją bibliotekę, która upraszcza wszystko, o czym wspomniałem dla obu węzłów.js i przeglądarki internetowej, a dodatkowo daje możliwość eksportu zestawu działa w piaskownicy.

 4
Author: asvd,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-16 23:23:22

Alternatywą byłoby użycie http://github.com/patriksimek/vm2 :

$ npm install vm2

Wtedy:

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

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

Jak wspomniano w komentarzach innych odpowiedzi.

Nie wiem, jak jest bezpieczny, ale przynajmniej twierdzi, że uruchamia niezaufany kod bezpiecznie (w README). I nie mogłem znaleźć żadnych oczywistych problemów bezpieczeństwa, o ile rozwiązania sugerowane w innych odpowiedziach tutaj.

 3
Author: Hiroshi Ichikawa,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-01 12:26:35