test online navegador habilitar gratis desactivar como chrome celular activar javascript browser sandbox

online - ¿Es posible que Sandbox JavaScript se ejecute en el navegador?



javascript online console (14)

¿De dónde viene este usuario de JavaScript?

No hay mucho que pueda hacer para incluir un código de usuario en su página y luego llamarlo desde su navegador (vea Greasemonkey, http://www.greasespot.net/ ). Es solo algo que hacen los navegadores.

Sin embargo, si almacena el script en una base de datos, luego lo recupera y eval (), luego puede limpiar el script antes de ejecutarlo.

Ejemplos de código que elimina todas las ventanas. y documento. referencias:

eval( unsafeUserScript .replace(/////.+/n|///*.*/*//, '''') // Clear all comments .replace(//s(window|document)/s*[/;/)/.]/, '''') // removes window. or window; or window) )

Esto intenta evitar que se ejecute lo siguiente (no probado):

window.location = ''http://mydomain.com''; var w = window ;

Hay muchas limitaciones que debería aplicar al script de usuario inseguro. Desafortunadamente, no hay un ''contenedor de espacio aislado'' disponible para JavaScript.

Me pregunto si es posible guardar en la caja de arena JavaScript que se ejecuta en el navegador para evitar el acceso a las funciones que normalmente están disponibles para el código JavaScript que se ejecuta en una página HTML.

Por ejemplo, supongamos que quiero proporcionar una API de JavaScript para que los usuarios finales puedan ejecutar manejadores de eventos cuando se producen "eventos interesantes", pero no quiero que esos usuarios accedan a las propiedades y funciones del objeto de window . ¿Puedo hacer esto?

En el caso más simple, digamos que quiero evitar que los usuarios llamen alert . Un par de enfoques que puedo pensar son:

  • Redefinir window.alert globalmente. No creo que este sea un enfoque válido porque otros códigos que se ejecutan en la página (es decir, cosas no creadas por los usuarios en sus manejadores de eventos) pueden querer usar alert .
  • Envíe el código del controlador de eventos al servidor para procesarlo. No estoy seguro de que enviar el código al servidor para que se procese es el enfoque correcto porque los controladores de eventos deben ejecutarse en el contexto de la página.

Quizás una solución donde el servidor procesa la función definida por el usuario y luego genera una devolución de llamada para ser ejecutada en el cliente ¿funcionaría? Incluso si ese enfoque funciona, ¿hay mejores formas de resolver este problema?


1) Supongamos que tiene un código para ejecutar:

var sCode = "alert(document)";

Ahora, supongamos que quieres ejecutarlo en una caja de arena:

new Function("window", "with(window){" + sCode + "}")({});

Estas dos líneas cuando se ejecutan fallarán, porque la función de "alerta" no está disponible desde la "caja de arena"

2) Y ahora desea exponer un miembro del objeto ventana con su funcionalidad:

new Function("window", "with(window){" + sCode + "}")({ ''alert'':function(sString){document.title = sString} });

De hecho, puede agregar comillas de escape y hacer otros pulidos, pero supongo que la idea es clara.


Como se menciona en otras respuestas, es suficiente con encarcelar el código en un iframe de espacio aislado (sin enviarlo al lado del servidor) y comunicarse con los mensajes. Sugeriría echar un vistazo a una pequeña biblioteca que creé principalmente debido a la necesidad de proporcionar alguna API al código que no es de confianza, tal como se describe en la pregunta: hay una oportunidad de exportar el conjunto particular de funciones directamente a la caja de arena donde el código que no es de confianza se ejecuta. Y también hay una demostración que ejecuta el código enviado por un usuario en una caja de arena:

http://asvd.github.io/jailed/demos/web/console/


Creé una biblioteca de espacio aislado llamada jsandbox que usa trabajadores web para el código evaluado de zona de jsandbox . También tiene un método de entrada para dar explícitamente datos de código de espacio aislado que de otro modo no podría obtener.

El siguiente es un ejemplo de la API:

jsandbox .eval({ code : "x=1;Math.round(Math.pow(input, ++x))", input : 36.565010597564445, callback: function(n) { console.log("number: ", n); // number: 1337 } }).eval({ code : "][];.]// (*# ($(! ~", onerror: function(ex) { console.log("syntax error: ", ex); // syntax error: [error object] } }).eval({ code : ''"foo"+input'', input : "bar", callback: function(str) { console.log("string: ", str); // string: foobar } }).eval({ code : "({q:1, w:2})", callback: function(obj) { console.log("object: ", obj); // object: object q=1 w=2 } }).eval({ code : "[1, 2, 3].concat(input)", input : [4, 5, 6], callback: function(arr) { console.log("array: ", arr); // array: [1, 2, 3, 4, 5, 6] } }).eval({ code : "function x(z){this.y=z;};new x(input)", input : 4, callback: function(x) { console.log("new x: ", x); // new x: object y=4 } });


Creo que js.js pena mencionar js.js aquí. Es un intérprete de JavaScript escrito en JavaScript.

Es aproximadamente 200 veces más lento que el JS nativo, pero su naturaleza lo convierte en un entorno de recinto de seguridad perfecto. Otro inconveniente es su tamaño: casi 600 kb, que en algunos casos puede ser aceptable para equipos de escritorio, pero no para dispositivos móviles.


De una manera fea pero quizás esto funcione para ti, tomé todos los globales y los redefiní en el alcance de la caja de arena, y agregué el modo estricto para que no puedan obtener el objeto global usando una función anónima.

function construct(constructor, args) { function F() { return constructor.apply(this, args); } F.prototype = constructor.prototype; return new F(); } // Sanboxer function sandboxcode(string, inject) { "use strict"; var globals = []; for (var i in window) { // <--REMOVE THIS CONDITION if (i != "console") // REMOVE THIS CONDITION --> globals.push(i); } globals.push(''"use strict";/n''+string); return construct(Function, globals).apply(inject ? inject : {}); } sandboxcode(''console.log( this, window, top , self, parent, this["jQuery"], (function(){return this;}()));''); // => Object {} undefined undefined undefined undefined undefined undefined console.log("return of this", sandboxcode(''return this;'', {window:"sanboxed code"})); // => Object {window: "sanboxed code"}

https://gist.github.com/alejandrolechuga/9381781


Eche un vistazo al ADsafe de Douglas Crockford :

ADsafe hace que sea seguro poner código de invitado (como publicidad con guiones de terceros o widgets) en cualquier página web. ADsafe define un subconjunto de JavaScript que es lo suficientemente potente como para permitir que el código de invitado realice interacciones valiosas, al tiempo que previene el daño o la intrusión malintencionados o accidentales. El subconjunto ADsafe puede verificarse mecánicamente con herramientas como JSLint, de modo que no sea necesaria una inspección humana para revisar el código de invitado por razones de seguridad. El subconjunto ADsafe también impone buenas prácticas de codificación, lo que aumenta la probabilidad de que el código de invitado se ejecute correctamente.

Puede ver un ejemplo de cómo usar ADsafe mirando los archivos template.html y template.js en el repositorio GitHub del proyecto .


Es más probable que un intérprete independiente de Javascript produzca un entorno limitado robusto que una versión enjaulada de la implementación del navegador incorporado. Ryan ya mencionó js.js , pero un proyecto más actualizado es JS-Interpreter . Los docs cubren cómo exponer varias funciones al intérprete, pero su alcance es muy limitado.


He estado trabajando en un sandbox js simplista para permitir a los usuarios crear applets para mi sitio. Aunque todavía tengo algunos desafíos al permitir el acceso DOM (parentNode simplemente no me permite mantener las cosas seguras = /), mi enfoque era simplemente redefinir el objeto ventana con algunos de sus miembros útiles / inofensivos, y luego eval () el usuario código con esta ventana redefinida como el alcance predeterminado.

Mi código "central" es el siguiente ... (No lo estoy mostrando por completo;)

function Sandbox(parent){ this.scope = { window: { alert: function(str){ alert("Overriden Alert: " + str); }, prompt: function(message, defaultValue){ return prompt("Overriden Prompt:" + message, defaultValue); }, document: null, . . . . } }; this.execute = function(codestring){ // here some code sanitizing, please with (this.scope) { with (window) { eval(codestring); } } }; }

Entonces, puedo instanciar un Sandbox y usar su ejecución () para ejecutar el código. Además, todas las nuevas variables declaradas dentro del código evaluado se vincularán en última instancia al ámbito execute (), de modo que no habrá nombres enfrentados ni problemas con el código existente.

Aunque los objetos globales seguirán siendo accesibles, los que deberían permanecer desconocidos para el código de espacio aislado se deben definir como proxies en el objeto Sandbox :: scope.

Espero que esto funcione para usted.


Puede envolver el código del usuario en una función que redefine los objetos prohibidos como parámetros; estos no estarían undefined cuando se los llame.

(function (alert) { alert ("uh oh!"); // User code }) ();

Por supuesto, los atacantes inteligentes pueden evitar esto inspeccionando el Javascript DOM y encontrando un objeto no reemplazado que contiene una referencia a la ventana.

Otra idea es escanear el código del usuario usando una herramienta como jslint . Asegúrate de que esté configurado para no tener variables preestablecidas (o: solo las variables que desees) y, luego, si se configuran o acceden algunos valores globales, no permitas que se use el script del usuario. De nuevo, podría ser vulnerable a recorrer el DOM: los objetos que el usuario puede construir utilizando literales podrían tener referencias implícitas al objeto de la ventana al que se podría acceder para escapar de la zona de pruebas.


Todos los proveedores de navegadores y la especificación HTML5 están trabajando hacia una propiedad de recinto de seguridad real para permitir iframes de espacio aislado, pero aún está limitada a la granularidad de iframe.

En general, ningún grado de expresiones regulares, etc. puede desinfectar con seguridad el JavaScript proporcionado por el usuario arbitrario, ya que degenera al problema de detención: - /


Una versión mejorada del código sandbox de trabajadores web de @ RyanOHara, en un solo archivo (no es necesario eval.js archivo eval.js adicional).

function safeEval(untrustedCode) { return new Promise(function (resolve, reject) { var blobURL = URL.createObjectURL(new Blob([ "(", function () { var _postMessage = postMessage; var _addEventListener = addEventListener; (function (obj) { "use strict"; var current = obj; var keepProperties = [ // required ''Object'', ''Function'', ''Infinity'', ''NaN'', ''undefined'', ''caches'', ''TEMPORARY'', ''PERSISTENT'', // optional, but trivial to get back ''Array'', ''Boolean'', ''Number'', ''String'', ''Symbol'', // optional ''Map'', ''Math'', ''Set'', ]; do { Object.getOwnPropertyNames(current).forEach(function (name) { if (keepProperties.indexOf(name) === -1) { delete current[name]; } }); current = Object.getPrototypeOf(current); } while (current !== Object.prototype); })(this); _addEventListener("message", function (e) { var f = new Function("", "return (" + e.data + "/n);"); _postMessage(f()); }); }.toString(), ")()"], {type: "application/javascript"})); var worker = new Worker(blobURL); URL.revokeObjectURL(blobURL); worker.onmessage = function (evt) { worker.terminate(); resolve(evt.data); }; worker.onerror = function (evt) { reject(new Error(evt.message)); }; worker.postMessage(untrustedCode); setTimeout(function () { worker.terminate(); reject(new Error(''The worker timed out.'')); }, 1000); }); }

Pruébalo:

https://jsfiddle.net/kp0cq6yw/

var promise = safeEval("1+2+3"); promise.then(function (result) { alert(result); });

Debería producir 6 (probado en Chrome y Firefox).


Google Caja es un traductor de fuente a fuente que "le permite poner HTML y JavaScript de terceros no confiables en línea en su página y aún así ser seguro".


EDITAR : aunque no conozco una forma de escapar de la lista blanca a continuación, también ejecutaría al trabajador desde un <iframe> espacio aislado, por las dudas, y recomendaría la recomendación js.js de @gronostaj si el agotamiento de la memoria es una preocupación.

Los trabajadores de la web proporcionan una forma conveniente de crear otro contexto de script, que luego se puede guardar de manera agresiva sin afectar al padre.

Una implementación que usa promesas:

function safeEval(untrustedCode) { return new Promise(function (resolve, reject) { var worker = new Worker(''eval.js''); worker.onmessage = function (e) { worker.terminate(); resolve(e.data); }; worker.onerror = function (e) { reject(new Error(e.message)); }; worker.postMessage(untrustedCode); setTimeout(function () { worker.terminate(); reject(new Error(''The worker timed out.'')); }, 1000); }); }

eval.js (probablemente querrás expandir la lista blanca):

(function (global) { ''use strict''; var _postMessage = postMessage; var _addEventListener = addEventListener; (function () { var current = global; var keepProperties = [ // required ''Object'', ''Function'', ''Infinity'', ''NaN'', ''undefined'', // optional, but trivial to get back ''Array'', ''Boolean'', ''Number'', ''String'', ''Symbol'', // optional ''Map'', ''Math'', ''Set'', ]; do { Object.getOwnPropertyNames(current).forEach(function (name) { if (keepProperties.indexOf(name) === -1) { delete current[name]; } }); current = Object.getPrototypeOf(current); } while (current !== Object.prototype); })(); _addEventListener(''message'', function (e) { var f = new Function('''', ''return ('' + e.data + ''/n);''); _postMessage(f()); }); })(this);

Los trabajadores no pueden acceder a la interfaz de usuario, pueden terminar por separado, no pueden vincular la interfaz de usuario o la secuencia de comandos en ejecución, y son estándar.