¿Cuáles son los problemas de seguridad con "eval ()" en JavaScript?

19

Cada vez que alguien menciona eval (), todo el mundo dice que hay "problemas de seguridad" con eso, pero nadie entra en detalles sobre lo que son. La mayoría de los navegadores modernos parecen ser capaces de depurar eval () tan bien como el código normal, y las afirmaciones de una disminución en el rendimiento de las personas son dudosas / dependen del navegador.

Entonces, ¿cuáles son los problemas, si los hay, asociados con eval ()? No he podido encontrar nada que pueda ser explotado con eval () en JavaScript. (Veo problemas con el código eval () 'ing en el servidor, pero eval (del lado del cliente) parece ser seguro.)

    
pregunta Stack Tracer 15.07.2015 - 17:50
fuente

4 respuestas

29

eval() ejecuta una cadena de caracteres como código. Utiliza eval() precisamente porque el contenido de la cadena no se conoce de antemano, o incluso se genera en el lado del servidor; Básicamente, necesita eval() porque el propio JavaScript generará la cadena a partir de datos que solo están disponibles de forma dinámica, en el cliente.

Por lo tanto, eval() tiene sentido en situaciones donde el código JavaScript generará código. Esto no es intrínsecamente malo , pero es difícil hacerlo de manera segura. Los lenguajes de programación están diseñados para permitir que un ser humano escriba instrucciones que una computadora entiende; a tal efecto, cualquier lenguaje está lleno de pequeñas peculiaridades y comportamientos especiales que se supone que ayudan al programador humano (por ejemplo, la adición automática de ';' al final de algunas declaraciones en JavaScript). Todo esto es muy bueno para la programación "normal"; pero cuando genere el código de otro programa, basándose en datos que pueden ser potencialmente hostiles (por ejemplo, un fragmento de cadena de otros usuarios del sitio), debe, como desarrollador del generador de código, conocer < em> todos estos caprichos, y evita que los datos hostiles los exploten de maneras dañinas.

En ese sentido, los generadores de código (y, por lo tanto, eval() ) incurren en los mismos problemas conceptuales que el SQL sin formato y su consecuencia, ataques de inyección SQL . Reunir en tiempo de ejecución una solicitud de SQL a partir de parámetros provistos externamente se puede hacer de manera segura, pero esto requiere una gran cantidad de detalles, por lo que el consejo habitual es no hacerlo. Esto se relaciona con el enigma habitual de la seguridad, es decir, que no es comprobable: puede probar si alguna parte del código funciona correctamente con datos correctos, pero no que nunca funcione incorrectamente con datos incorrectos. De manera similar, es posible usar eval() de forma segura, pero en la práctica es tan difícil que no se recomienda.

Todo esto se dice en toda la generalidad. En su contexto específico, eval() podría ser seguro. Sin embargo, se requiere cierto esfuerzo para tener un contexto seguro para el uso de eval() , que realmente necesita eval() .

    
respondido por el Thomas Pornin 15.07.2015 - 18:03
fuente
12

eval () es un posible vector para secuencias de comandos entre sitios.
En circunstancias normales, un atacante que intente XSS podría querer que las secuencias de comandos <script></script> pasen la codificación, los filtros o los cortafuegos que estén en su lugar. Si eval () está operando en las entradas del usuario, elimina la necesidad de etiquetas de script.

Eval está presente en muchos scripts maliciosos porque ayuda a ofuscar el código y / o esconder los caracteres prohibidos en los filtros. Por esta razón, eval () a menudo se comprueba en la entrada del usuario. Por lo tanto, al usar eval () usted está, potencialmente, proporcionando al atacante una de sus herramientas necesarias. Estoy robando un banco y sé que no tengo que pasar un arma por ningún detector de metales porque hay un montón en el paraguas dentro del edificio.

    
respondido por el mcgyver5 15.07.2015 - 18:23
fuente
2

Como lo explicaron otros, uno puede usar eval para crear dinámicamente el código, lo que dificulta la comprensión del flujo de control del programa. Pero, no considero que eval sea mucho más malvado que todas las otras formas de generar código en tiempo de ejecución, como document.write(...) , object.innerHTML(...) y otros. Si bien estos se usan principalmente para cambiar el DOM del programa, también se usan para insertar un nuevo código (es decir, agregar una declaración de script al código, o un nuevo elemento con algún controlador onXXXX, etc.).

Y mientras que eval se usa a menudo en ataques (XSS, publicidad maliciosa ...) para eludir los filtros u ocultar el propósito real del código, a menudo se usa de forma ofuscada, es decir, código como z='ev'; z+='al'; v=window; v[z]("alert(1)") . Esto significa que no está en el lado seguro si simplemente trata de filtrar el código con llamadas explícitas de eval, ya sea porque la llamada está confusa o si se usan funciones "buenas", como innerHTML, para propósitos incorrectos.

    
respondido por el Steffen Ullrich 15.07.2015 - 19:10
fuente
2

Además de los puntos importantes que se mencionan aquí, me gustaría aclarar: lo que está tratando esencialmente con cada vez que usa eval () es tener que responder las siguientes preguntas:

  • ¿Vale la pena asegurarlo?
  • ¿Qué tan bien puedo asegurarlo y ese nivel es aceptable?
  • ¿Qué tan seguro puedo tener de que se mantendrá seguro en futuras evoluciones del código base y el equipo de desarrollo?
  • ¿Cómo se comparan el riesgo y la cantidad de esfuerzo requerido por lo anterior con el esfuerzo de construir el código de tal manera que no se requiera la ejecución de código generado dinámicamente y posiblemente desconocido?

Si ha pensado en estas preguntas más completamente de lo que lo haría un atacante y aún está considerando usar eval (), hágalo. Es posible que descubra que está cansado de pensar eso a lo largo de su carrera de desarrollo y comience a evitar su uso simplemente por principio.

    
respondido por el S.C. 15.07.2015 - 19:50
fuente

Lea otras preguntas en las etiquetas