Rendere i WebWorkers un ambiente sicuro

In una ricerca per avere un’interfaccia in grado di eseguire codice javascript arbitrario all’interno del browser, senza avere un buco di sicurezza delle dimensioni di una tipica battuta yo-mama, Esailija ha proposto di utilizzare Web Workers . Funzionano in un ambiente semi-sandbox (nessun accesso DOM e già all’interno del browser) e possono essere uccisi in modo che l’utente non possa inserirli in un ciclo infinito.

Ecco l’esempio da lui presentato: http://tuohiniemi.fi/~runeli/petka/workertest.html (apri la tua console)

jsfiddle (solo Google Chrome)

Ora, questa sembra una buona soluzione; tuttavia, è completo (o si avvicina completo)? C’è qualcosa di evidente mancante?

L’intera cosa (dato che è collegata a un bot) può essere trovata su github: worker , Evaluator

principale:

workercode = "worker.js"; function makeWorkerExecuteSomeCode( code, callback ) { var timeout; code = code + ""; var worker = new Worker( workercode ); worker.addEventListener( "message", function(event) { clearTimeout(timeout); callback( event.data ); }); worker.postMessage({ code: code }); timeout = window.setTimeout( function() { callback( "Maximum execution time exceeded" ); worker.terminate(); }, 1000 ); } makeWorkerExecuteSomeCode( '5 + 5', function(answer){ console.log( answer ); }); makeWorkerExecuteSomeCode( 'while(true);', function(answer){ console.log( answer ); }); var kertoma = 'function kertoma(n){return n === 1 ? 1 : n * kertoma(n-1)}; kertoma(15);'; makeWorkerExecuteSomeCode( kertoma, function(answer){ console.log( answer ); }); 

lavoratore:

 var global = this; /* Could possibly create some helper functions here so they are always available when executing code in chat?*/ /* Most extra functions could be possibly unsafe */ var wl = { "self": 1, "onmessage": 1, "postMessage": 1, "global": 1, "wl": 1, "eval": 1, "Array": 1, "Boolean": 1, "Date": 1, "Function": 1, "Number" : 1, "Object": 1, "RegExp": 1, "String": 1, "Error": 1, "EvalError": 1, "RangeError": 1, "ReferenceError": 1, "SyntaxError": 1, "TypeError": 1, "URIError": 1, "decodeURI": 1, "decodeURIComponent": 1, "encodeURI": 1, "encodeURIComponent": 1, "isFinite": 1, "isNaN": 1, "parseFloat": 1, "parseInt": 1, "Infinity": 1, "JSON": 1, "Math": 1, "NaN": 1, "undefined": 1 }; Object.getOwnPropertyNames( global ).forEach( function( prop ) { if( !wl.hasOwnProperty( prop ) ) { Object.defineProperty( global, prop, { get : function() { throw new Error( "Security Exception: cannot access "+prop); return 1; }, configurable : false }); } }); Object.getOwnPropertyNames( global.__proto__ ).forEach( function( prop ) { if( !wl.hasOwnProperty( prop ) ) { Object.defineProperty( global.__proto__, prop, { get : function() { throw new Error( "Security Exception: cannot access "+prop); return 1; }, configurable : false }); } }); onmessage = function( event ) { "use strict"; var code = event.data.code; var result; try { result = eval( '"use strict";\n'+code ); } catch(e){ result = e.toString(); } postMessage( "(" + typeof result + ")" + " " + result ); };