2009-03-14 16 views
18

Una solicitud ajax me devuelve una matriz JSON estándar llena con las entradas de mi usuario. La entrada se ha desinfectado, y utilizando la función eval(), puedo crear fácilmente mi objeto javascript y actualizar mi página ...Evaluar es malo ... ¿Qué debería usar en su lugar?

Así que aquí está el problema. No importa cuánto trate de desinfectar las entradas, prefiero no usar la función eval(). Revisé google para ver cómo usar "JSON en AJAX sin evaluación" y me he encontrado con varios métodos diferentes ...

¿Cuál debo usar? ¿Existe una forma estándar, comprobada y segura de hacer esto?

+0

Tenga una mirada en: http://stackoverflow.com/questions/86513/why-is-using-javascript-eval-function-a-bad -idea –

+0

Creo que eval en este caso no es malo ... Tal vez deberías echarle un vistazo a esa pregunta: [¿Cuándo JavaScript's eval() no es malvado?] (http://stackoverflow.com/questions/197769/ when-is-javascripts-eval-not-evil) –

Respuesta

20

json.org tiene un bonito javascript library

uso simple:

JSON.parse('[{"some":"json"}]'); 
JSON.stringify([{some:'json'}]); 

Editar: Como se ha señalado en los comentarios, este utiliza eval si se mira a través de su fuente (aunque parece ser desinfectado primero)

que deben evitarse por completo, un vistazo a json_parse o json-sans-eval

json2.js es insegura, json_parse.js es lento, JSON-sans-eval.js es no validador

+7

También usa eval. –

+2

Utiliza eval solo como respaldo para navegadores que no admite nativamente el objeto JSON, y si no tiene la función "analizar". –

+0

_json2.js es inseguro_ ** de donde es eso? tiene 1mb de regex que sintetiza la cadena antes usa eval ** –

8

Yo diría, una vez que la entrada se desinfecta, eval es la mejor manera de hacerlo. Si su servidor se ve comprometido, las personas podrán enviar los scripts que quieran al cliente de todos modos. Entonces poner una evaluación no es un gran riesgo de seguridad. Si le preocupa que las personas manipulen los paquetes antes de que lleguen al cliente, nuevamente, los mismos scripts se pueden modificar.

No te preocupes por eval. Pero asegúrese de envolverlo en un bloque try ... catch para que sus usuarios no obtengan errores JS si su JSON se destruye.

:)

0

comparar con el patrón de diseño comando: http://en.wikipedia.org/wiki/Command_pattern. Dado esto, puede definir con precisión las operaciones que un cliente puede ejecutar y su aplicación será tan segura como la interpretación subyacente.

0

Depende de lo que intente lograr con el saneamiento. He tenido un gran éxito con el soporte del framework prototype para JSON y una evaluación segura.

10

¿Hay una forma estándar y probada segura de hacer esto?

Se propone una forma estándar de hacerlo en la próxima versión de JavaScript de ECMAScript 3.1: JSON.parse.

Será compatible con IE8, Firefox 3.1/3.5 y muy probablemente con los otros buscadores populares en el futuro. Mientras tanto, puedes recurrir a, o usar exclusivamente, eval(). El mal puede o no ser; ciertamente será más lento que JSON.parse. Pero esa es la forma habitual de analizar JSON hoy.

Si un atacante es capaz de inyectar JavaScript malicioso en el contenido que está escupiendo a través de JSON, tiene más problemas de los que preocuparse que eval-is-evil.

2

Para convertir JSON de forma segura en un objeto JS, debe usar un analizador JSON como la función JSON.parse() proporcionada por this library.

0

Si está seguro de que no hay riesgo de inyección y no está eval()ing en un bucle, utilice eval(). Se comparará favorablemente con otras opciones que, sin duda, serán más lentas, podrían romperse y requerirán que el cliente descargue código adicional.

0

"robado" de jQuery

// Try to use the native JSON parser first 
return window.JSON && window.JSON.parse ? 
    window.JSON.parse(data) : 
    (new Function("return " + data))(); 
0

Edición: El eval problema plantea es que se ejecuta en el ámbito global

eval.call(document, "console.log(this)") 
eval.call(navigator, "console.log(this)") 
eval.call(window, "console.log(this)") 
(function(){eval.call(document, "console.log(this)")})() 
>Window 

Escenario:

usted asume están utilizando atributos individuales en el código de marcado de varios docum ent-elementos tales como un atributo onvisible

<img src="" onvisible="src='http://www.example.com/myimg.png';"> 

¿Le gustaría obtener todos los elementos con este atributo, gire el contenido cuerdas onvisible en un cierre y ponerlo en una cola de manejador de sucesos. Aquí es donde el constructor de la Función JS entra en juego.

Function === 0..constructor.constructor 
>true 

Function('return [this, arguments]').call(window, 1,2,3) 
>Window, Arguments[3]] 
Function('return [this, arguments]').call(document, 1,2,3) 
>Document, Arguments[3]] 
Function('return [this, arguments]').call(navigator, 1,2,3) 
>Navigator, Arguments[3]]  

Poniendo todo junto:

var eventQueue = []; 
var els = document.querySelectorAll('[onvisible]'); 

for (var el in els) { 
    var jscode = els[el].getAttribute('onvisible'); 
    eventQueue.push({el:els[el], cb:Function(jscode)}) 
} 

//eventQueue[0].cb.call(scope, args); 
Cuestiones relacionadas