ofuscar - ¿Cómo puedo proteger el contenido de JavaScript enviado por el usuario no confiable?
proteger archivos js (4)
Algunas ideas de herramientas que podrían ser útiles en su aplicación: atacan el problema desde dos direcciones diferentes: Caja compila el código JavaScript que no es de confianza con algo que es seguro, mientras que AdSafe define un subconjunto de JavaScript que es seguro de usar.
Caja
El compilador de Caja es una herramienta para hacer que los HTML, CSS y JavaScript de terceros sean seguros para incrustar en su sitio web. Permite una rica interacción entre la página de incrustación y las aplicaciones integradas. Caja utiliza un modelo de seguridad con capacidad de objetos para permitir una amplia gama de políticas de seguridad flexibles, de modo que su sitio web pueda controlar de manera efectiva lo que el código de terceros integrado puede hacer con los datos del usuario.
AdSafe
ADsafe hace que sea seguro poner código de invitado (como publicidad con guiones de terceros o widgets) en una 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.
Necesito presentar scripts enviados por el usuario en mi sitio (algo así como jsfiddle ). Quiero que los scripts se ejecuten en los navegadores visitantes de forma segura, aislados de la página en la que se publican. Dado que el código es enviado por los usuarios, no hay garantía de que sea confiable.
Ahora mismo puedo pensar en tres opciones:
- Sirva el contenido enviado por el usuario en un iframe de un dominio diferente y confíe en la política de origen idéntico. Esto requeriría configurar un dominio adicional que me gustaría evitar si es posible. Creo que así es como lo hace jsfiddle. La secuencia de comandos todavía puede hacer algún daño, cambiando
top.location.href
por ejemplo, que es menos que ideal. http://jsfiddle.net/PzkUw/ - Use el atributo sandbox . Sospecho que esto no está bien soportado en todos los navegadores.
- Sanitize los scripts antes de servirlos . Preferiría no ir allí.
¿Hay alguna otra solución o recomendación sobre lo anterior?
Actualizar
Si, como sospecho, la primera opción es la mejor solución, ¿qué puede hacer un script malicioso que no sea cambiar la ubicación de la ventana superior y cómo puedo evitarlo? Puedo manipular o rechazar ciertos guiones basados en el análisis de código estático, pero esto es hard dada la cantidad de formas en que se puede acceder a los objetos y la dificultad para analizar javascript estáticamente en general. Por lo menos, requeriría un analizador completo y una serie de reglas complejas (algunas, pero sospecho que no todas, de las cuales están presentes en JSLint).
Como se mencionó, el atributo sandbox
del iframe
ya es compatible con los principales navegadores, pero también sugeriría una solución mixta: iniciar un trabajador web dentro del iframe de espacio aislado. Eso daría un hilo separado y protegería el evento del DOM del sandbox iframe del código que no es de confianza. Así es como funciona mi biblioteca Jailed . Además, puede solucionar cualquier restricción exportando cualquier conjunto de funciones al entorno limitado.
Cree una interfaz de mensajes bien definida y use JavaScript Web Worker para el código que desea crear en la zona de pruebas. Trabajadores web HTML5
Los Trabajadores Web no tienen acceso a los siguientes objetos DOM.
El objeto ventana
El objeto del documento
El objeto principal
Por lo tanto, no pueden redirigir su página o alterar datos en ella.
Puede crear una plantilla y una interfaz de mensajería bien definida para que los usuarios puedan crear scripts de trabajador web, pero su secuencia de comandos tendrá la última palabra sobre lo que se manipula.
EDITAR Comentario de Jordan Gray al conectar una biblioteca de JavaScript que parece hacer lo que describí anteriormente. https://github.com/eligrey/jsandbox
Si quieres guardar un fragmento de código en la zona de pruebas eliminando su acceso para decir la ventana , el documento y el elemento padre , puedes lograrlo envolviéndolo en un cierre donde estas son variables locales vacías:
(function(window, document, parent /* Whatever you want to remove */){
console.log(this); // Empty object
console.log(window); // undefined
console.log(document); // undefined
console.log(parent); // undefined
}).call({});
Llamarlo con un objeto vacío es importante porque de lo contrario esto apuntará al objeto ventana