2013-07-07 9 views
34

Ich möchte die Möglichkeit haben, dass Benutzer beliebigen JavaScript-Code senden können, der dann an einen Node.JS-Server gesendet und sicher ausgeführt wird, bevor die Ausgabe an mehrere Clients zurückgesendet wird (als JSON). Die Funktion eval kommt mir in den Sinn, aber ich weiß, dass dies mehrere Sicherheitsbedenken hat (der vom Benutzer eingegebene Code könnte auf Nodes Datei-API usw. zugreifen). Ich habe einige Projekte wie Microsoft Web Sandbox und Google Caja gesehen, die die Ausführung von saniertem Markup und Skript (zum Einbetten von Drittanbieter-Anzeigen auf Websites) erlauben, aber es scheint, dass dies clientseitige Tools sind und ich bin mir nicht sicher, ob sie dies können sicher in Node verwendet werden.sicher Sandbox und Ausführen von Benutzer eingereichten JavaScript?

Gibt es eine Standardmethode zum Sandboxing und Ausführen von nicht vertrauenswürdigem JavaScript in Node, um die Ausgabe zu erhalten. Ist es ein Fehler, diese Server-Seite zu versuchen?

EDIT: Es ist nicht wichtig, dass der Benutzer die vollen Fähigkeiten von JavaScript nutzen kann, in der Tat wäre es besser, in der Lage zu sein, auszuwählen, welche APIs für den Benutzercode bereitgestellt werden.

EDIT: Ich werde fortfahren und aktualisieren mit dem, was ich gefunden habe. Dieses Sandcastle-Modul (bcoe/sandcastle) scheint darauf abzielen, das zu tun, was ich vorhabe. Ich bin mir nicht sicher, wie sicher es ist, aber da ich nichts für zu wichtig halte, denke ich, werde ich es versuchen. Ich werde meine eigene Antwort hinzufügen, wenn ich das erfolgreich machen kann.

+0

Warum muss es auf Ihrem Server und nicht auf dem Client ausgeführt werden? – delnan

+2

Ich denke, das ist ein Fehler, aber Sie könnten versuchen, den Knoten 'vm' Zeug - http: //nodejs.org/api/vm.html – JoshRagem

+1

Dies ist für ein Programmier-Spiel-Konzept zum Spaß, ich kann nicht vertrauen Clients, um den Code auszuführen. Ich möchte es aus diesem Grund Server-Seite tun, und da die Ausgabe serialisiert und an 1 oder mehrere andere Clients gesendet wird. Es sieht aus wie das VM-Modul oder etwas, was es ist, was ich will. –

Antwort

3

Diese Antwort ist veraltet wie GF3 nicht der Schutz vor Sandbox nicht bieten

http://gf3.github.io/sandbox/ zu brechen - es nutzt require('child_process') statt require('vm').

+0

Ich gehe voran und akzeptiere, ich werde sowohl die Sandbox als auch das Sandcastle-Modul betrachten, mit dem ich in den nächsten Tagen verbunden bin. Vielen Dank. –

+1

Irreführe nicht, gf3/sandbox verwendet sowohl die untergeordneten Prozesse als auch die vm-Module, überprüfe den Code. Und alle Sandboxing-Lösungen machen das Gleiche. –

+5

Für zukünftige Zuschauer, derzeit so wie es aussieht, ist gf3 ausnutzbar und kann ausbrechen. –

4

Unter Node.js können Sie einen Sandbox-Kindprozess erstellen, aber Sie müssen auch den Code mit "use strict"; anhängen, andernfalls ist es möglich, die Sandbox mit arguments.callee.caller zu brechen.

Nicht sicher, warum Sie es an den Server senden müssen, da der Code auch in einem Sandkasten-Web-Mitarbeiter ausgeführt werden kann.

Schauen Sie sich auch meine Jailed Bibliothek an, die alles, was gerade für Node.js und den Webbrowser erwähnt wurde, vereinfacht und zusätzlich die Möglichkeit bietet, einen Satz von Funktionen in die Sandbox zu exportieren.

+2

Zu diesem Zeitpunkt ist Jailed defekt : https://github.com/asvd/jailed/issues/33 – arve0

+0

@ arve0 Sie haben Recht, eingesperrt wurde unter Knoten kompromittiert, wird das Update vorbereitet – asvd

+2

Alternative: https://github.com/patriksimek/vm2 Anscheinend Seien Sie sicher, aber wenn Sie die logarithmischen Potentialausbrüche sehen, wäre ich vorsichtig. – arve0

9

Sie können Sandbox-Unterstützung in NodeJS mit vm.runInContext ('js Code', Kontext), Probe in api-Dokumentation verwenden:

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 } 

WARNEN: Wie von "S4Y" darauf hingewiesen scheint perfekt zu sein. Bitte sehen Sie sich die Kommentare an.

+1

Dies scheint nicht sicher zu sein, zB: 'vm.runInNewContext ('this.constructor.constructor (" return process ")(). Exit()');' (aus dem vm2 README: https: // github .com/patriksimek/vm2). – s4y

2

Eine Alternative wäre http://github.com/patriksimek/vm2 zu verwenden:

$ npm install vm2 

dann:

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

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

wie in den Kommentaren der anderen Antworten erwähnt.

Ich weiß nicht, wie sicher es ist, aber es behauptet zumindest, dass es nicht vertrauenswürdigen Code sicher läuft (in seiner README).Und ich konnte keine offensichtlichen Sicherheitsprobleme finden, soweit Lösungen in anderen Antworten hier vorgeschlagen werden.