¿Qué constituye el "uso indebido" de la función Eval de javascript? [cerrado]

13

Eval es una característica del lenguaje notoriamente controvertida. Douglas Crockford lo rechaza de plano. Me pregunto qué riesgos específicos conlleva Eval. De acuerdo con esta pregunta , Improper use of eval opens up your code for injection attacks .

¿Cuáles son algunos usos incorrectos del comando Eval y qué agujeros de seguridad se abren?

    
pregunta Derek Adair 22.03.2011 - 04:30

7 respuestas

30

Antes, cuando estaba implementando el motor JScript, recomendaba tener impresas las camisetas de EVAL IS EVIL pero, lamentablemente, nunca lo logramos.

Mi mayor problema con eval no es el ataque obvio de inyección de código malintencionado, aunque ciertamente es una gran preocupación. Mi mayor problema con esto es que la gente tiende a usarlo como un Really Big Hammer para resolver problemas realmente pequeños. La mayoría de los usos del mundo real que vi de "eval" en la naturaleza cuando estaba en el equipo de JScript podrían haberse resuelto de forma trivial utilizando una tabla de búsqueda; y como cada objeto en JScript ya es una tabla de búsqueda , no es como si fuera una carga onerosa. Eval vuelve a iniciar el compilador y destruye completamente la capacidad del compilador para optimizar su código .

Para más ideas en este sentido, vea mis artículos de 2003 sobre el tema:

Maldad general:

enlace

Inyección ataque maldad:

enlace

    
respondido por el Eric Lippert 22.03.2011 - 05:33
4

La mayoría de los agujeros de seguridad son el mismo tipo de agujeros que con la inyección de SQL, es decir, concatenando la entrada del usuario en el código JavaScript. La diferencia es que si bien hay formas de garantizar que esto no ocurra con SQL, no hay mucho que puedas hacer con JavaScript.

Como ejemplo trivial e inútil, una calculadora de JavaScript simplista:

textbox1.value = eval(textbox2.value);

Unos ejemplos de uso correctos son algunos de los empaquetadores de JavaScript que comprimen JavaScript extrayendo palabras comunes y reemplazándolas con reemplazos cortos de 1-2 caracteres. Luego, el empaquetador envía todo esto junto con el código de reemplazo de cadena basado en el diccionario generado y, a continuación, muestra el resultado.

    
respondido por el Matthew Scharley 22.03.2011 - 05:26
1

Hay algunas cosas que son imposibles de hacer en JS sin una función similar a eval ( eval , Function y quizás más).

Tomar apply por ejemplo. Es fácil de usar cuando se usa en llamadas a funciones comunes:

foo.apply(null, [a, b, c])

¿Pero cómo haría esto para los objetos que está creando a través de una nueva sintaxis?

new Foo.apply(null, [a, b, c]) no funciona, ni tampoco formularios similares.

Pero puede evitar esta limitación a través de eval o Function (yo uso Function en este ejemplo):

Function.prototype.New = (function () {
    var fs = [];
    return function () {
        var f = fs[arguments.length];
        if (f) {
            return f.apply(this, arguments);
        }
        var argStrs = [];
        for (var i = 0; i < arguments.length; ++i) {
            argStrs.push("a[" + i + "]");
        }
        f = new Function("var a=arguments;return new this(" + argStrs.join() + ");");
        if (arguments.length < 100) {
            fs[arguments.length] = f;
        }
        return f.apply(this, arguments);
    };
}) ();

Ejemplo:

Foo.New.apply(null, [a, b, c]) ;

Por supuesto, usted podría construir manualmente las funciones que utiliza Function.prototype.New , pero no solo es detallado, sino que (por definición) tiene que ser finito. Function permite que el código funcione para cualquier número de argumentos.

    
respondido por el Thomas Eding 14.08.2013 - 20:37
1

Una respuesta un tanto directa de mi parte fue el desarrollo de un área de prueba de API orientada al desarrollador. Dimos un área de texto en una página y un botón Ejecutar. El punto central de la página era que pudieran probar cosas en Javascript con nuestra API de comunicación iframe que no era tan fácil de hacer en un entorno local.

Cualquier cosa maliciosa que pudiera haberse hecho en ese caso también podría haber sido hecha por el desarrollador abriendo sus herramientas F12.

    
respondido por el Katana314 14.08.2013 - 22:23
0

Estoy de acuerdo en que rara vez debería usarse, pero he encontrado un caso de uso poderoso para eval .

Hay una nueva función experimental en Firefox llamada asm.js con la que he estado trabajando. Permite que un subconjunto limitado del lenguaje Javascript se compile en código nativo. Sí, esto es muy impresionante, pero tiene limitaciones. Puede pensar que el subconjunto limitado de Javascript es un lenguaje tipo C incrustado en Javascript. Realmente no está destinado a ser leído o escrito por humanos.

Este subconjunto limitado de Javascript no me permite inyectar mi código generado en tiempo de ejecución en el código compilado una vez que se haya compilado.

He escrito un código que le permite a un usuario escribir, en notación familiar, una expresión matemática, y convertirla al vuelo al código asm.js. A menos que quisiera que el código se procesara en el lado del servidor (que no lo hago), eval es la única herramienta que me permite procesar el código resultante en tiempo real.

    
respondido por el Rice Flour Cookies 29.08.2014 - 19:10
0

Como han señalado otros, lo más importante cuando se trabaja con eval es mantenerlo seguro. Para eso, desea realizar una comprobación exhaustiva de los argumentos y mantener simple el código ed. eval ya que generalmente es mucho más difícil mantener y asegurar el código generado en tiempo de ejecución.

Dicho esto, disfruto usar eval para dos tipos de cosas (aunque es probable que haya alternativas mejores y menos malvadas):

  1. Dado que eval es una forma de "código de almacenamiento en caché explícito", se puede usar para mejorar el rendimiento. Tenga en cuenta que los optimizadores siempre se están mejorando, pero simplemente no hay garantía de lo que pueden hacer por usted. Al hacer las cosas explícitas en el código, realmente puede ayudar al optimizador a tomar decisiones más inteligentes.
  2. También se puede usar para proporcionar formas básicas de seguridad de tipos, así como otras características de lenguaje que JS carece, sin deteriorar el rendimiento.

Este el enfoque de iterador de objetos precompilados , por ejemplo, muestra claros beneficios de rendimiento cuando se utiliza eval para la iteración de propiedades de objetos. También muestra los inicios de un sistema de tipo poderoso que puede proporcionar una comprobación de restricciones implícita y mucho más, a un costo muy bajo o gratuito.

Muchos desarrolladores experimentados de Javascript probablemente señalarían que este es un agujero de conejo, ya que, si empiezas a escribir Javascript de esta manera, esencialmente cambias la forma en que usas el idioma. Sin embargo, eso no necesariamente es algo malo para aquellos que disfrutan de Javascript, pero también les faltan características fundamentales del lenguaje que solo se pueden lograr cambiando la forma en que usamos el idioma en sí.

    
respondido por el Domi 09.09.2014 - 12:28
-3

Tengo una situación en la que eval parece ser el camino a seguir, evaluar una cadena y devolver una variable existente cuyo nombre es el mismo que la cadena.

Tengo varias tablas: table1ResultsTable, table2ResultsTable, tableNResultsTable. Tengo variables configuradas con los mismos nombres, que son objetos de datos de jQuery. Los uso para configurar las tablas y llamar a las funciones de datos de jQuery en ellas.

Cada tabla tiene una clase="tabla de resultados" asignada. Ahora, necesito obtener la variable cuando se hace clic en la tabla. Estoy haciendo esto:

$('resultsTable).on('click', 'td', function(event) {
    var cResultsTable = eval(event.target.parentElement.parentElement.parentElement.id);
    [etc]
});

Entonces obtengo el ID de la tabla en la que se hizo clic en la celda, que tiene el mismo nombre que la variable de objeto de datos correspondiente a ella. Si alguien tiene una sugerencia para una mejora, me gustaría saberlo.

    
respondido por el BobRodes 14.08.2013 - 16:46

Lea otras preguntas en las etiquetas