2013-07-07 19 views
34

Mi piacerebbe poter consentire agli utenti di inviare codice JavaScript arbitrario, che viene quindi inviato a un server Node.JS ed eseguito in modo sicuro prima che l'output venga inviato a più client (come JSON). Mi viene in mente la funzione eval, ma so che questo ha diversi problemi di sicurezza (il codice inviato dall'utente sarebbe in grado di accedere all'API file del Nodo, ecc.). Ho visto alcuni progetti come Microsoft Web Sandbox e Google Caja che consentono l'esecuzione di markup e script sanificati (per incorporare annunci di terze parti sui siti Web), ma sembra che si tratti di strumenti lato client e non sono sicuro che possano essere usato con sicurezza all'interno del nodo.Sandbox in modo sicuro ed esegui JavaScript inviato dall'utente?

Esiste un modo standard per sandbox ed esegue JavaScript non attendibile nel nodo, ottenendo l'output. È un errore provare e fare questo lato server?

EDIT: Non è importante che l'utente sia in grado di sfruttare tutte le funzionalità di JavaScript, infatti sarebbe preferibile poter selezionare e scegliere quali API sarebbero fornite al codice utente.

MODIFICA: Ho intenzione di andare avanti e aggiornare con quello che ho trovato. Questo modulo Sandcastle (bcoe/sandcastle) sembra mirare a fare ciò che ho in mente. Non sono sicuro di quanto sia sicuro, ma dal momento che questo non è per niente di troppo importante, penso che lo farò se lo provassi. Aggiungerò la mia risposta se riuscirò a farlo correttamente.

+0

Perché deve essere eseguito sul server, piuttosto che sul client? – delnan

+2

Penso che questo sia un errore, ma potresti provare il nodo "vm" - http: //nodejs.org/api/vm.html – JoshRagem

+1

Questo è per un concetto di gioco di programmazione per divertimento, non posso fidarmi del i client per eseguire il codice. Voglio farlo lato server per questo motivo e perché l'output verrà serializzato e inviato a 1 o più altri client. Sembra che il modulo vm o qualcosa che lo avvolge sia quello che voglio. –

risposta

3

Questa risposta è obsoleto come GF3 non fornisce protezione contro sandbox rottura

http://gf3.github.io/sandbox/ - usa require('child_process') invece di require('vm').

+0

Ho intenzione di andare avanti e accettare, guarderò sia sandbox che il modulo sandcastle che ho collegato a sopra nei prossimi giorni. Grazie. –

+1

Non fuorviare, gf3/sandbox utilizza entrambi i moduli figlio e vm, controllare il codice. E tutte le soluzioni sandboxing fanno lo stesso. –

+5

Per i futuri spettatori, attualmente così com'è gf3 è sfruttabile e può essere interrotto. –

4

In Node.js è possibile creare un processo figlio in modalità sandbox, ma è anche necessario aggiungere il codice con "use strict";, altrimenti è possibile interrompere la sandbox con arguments.callee.caller.

Non sicuro del motivo per cui è necessario inviarlo al server, perché il codice può anche essere eseguito in un web worker sandbox.

Dai anche un'occhiata alla mia libreria Jailed che semplifica tutto quanto appena menzionato sia per Node.js che per browser Web e offre inoltre l'opportunità di esportare un set di funzioni nella sandbox.

+2

In questo momento, il Jailed è rotto : https://github.com/asvd/jailed/issues/33 – arve0

+0

@ arve0 hai ragione, la prigione è stata compromessa sotto il nodo, la correzione è in fase di preparazione – asvd

+2

Alternativa: https://github.com/patriksimek/vm2 Sembra essere al sicuro, ma vedendo i potenziali scassi del registro, starei attento. – arve0

9

È possibile utilizzare il supporto sandbox in nodejs con vm.runInContext ('js codice', contesto), campione in documentazione 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 } 

avvertono: Come sottolineato da "s4y" si sembra essere coperto. Si prega di guardare i commenti.

+1

Questo non sembra essere sicuro, ad esempio: 'vm.runInNewContext ('this.constructor.constructor (" processo di ritorno ")(). Exit()');' (dal README di vm2: https: // github .com/patriksimek/VM2). – s4y

2

Un'alternativa sarebbe quella di utilizzare http://github.com/patriksimek/vm2:

$ npm install vm2 

poi:

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

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

come accennato nei commenti di altre risposte.

Non so quanto sia sicuro, ma almeno afferma di eseguire il codice non sicuro in modo sicuro (nel suo README).E non sono riuscito a trovare alcun ovvio problema di sicurezza per quanto riguarda le soluzioni suggerite in altre risposte qui.

Problemi correlati