Pregunta

Una solicitud ajax me devuelve una matriz JSON estándar llena de 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 ...

Entonces, aquí está el problema. No importa cuánto intente desinfectar las entradas, prefiero no usar la función eval (). He comprobado en google las formas de usar " JSON en AJAX sin eval " y me he encontrado con diferentes métodos ...

¿Cuál debo usar? ¿Existe una manera estándar y segura de hacerlo?

¿Fue útil?

Solución

json.org tiene una buena biblioteca de javascript

uso simple:

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

Editar : Como se señaló en los comentarios, esto utiliza eval si mira a través de su fuente (aunque parece que se desinfecta primero)

para evitarlo por completo, mire json_parse o json-sans-eval

json2.js es inseguro, json_parse.js es lento, json-sans-eval.js no es válido

Otros consejos

  

¿Existe una forma estándar y segura de hacerlo?

Hay una forma estándar propuesta de hacer esto, en la próxima versión de JavaScript ECMAScript 3.1: JSON.parse .

Será compatible con IE8, Firefox 3.1 / 3.5 y muy probablemente los otros navegadores populares en el futuro. Mientras tanto, puede recurrir a, o usar exclusivamente, eval (). Malvado 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 puede inyectar JavaScript malicioso en el contenido que está escupiendo a través de JSON, tiene mayores problemas de los que preocuparse que eval-is-evil.

Diría que, una vez que se desinfecte la entrada, 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. Por lo tanto, 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 scripts pueden modificarse.

No te preocupes por eval. Pero asegúrese de envolverlo en un intento ... bloque de captura para que sus usuarios no reciban errores de JS si su JSON se daña.

:)

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

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

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

Si está seguro de que no hay riesgo de inyección y no está eval () ing en un bucle, entonces use 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.

" 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))();

Problema: El problema que plantea Eval 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

Scenario:

Suponga que está utilizando atributos individuales en el código de marcado de varios elementos del documento, como un atributo visible

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

Desea obtener todos los elementos con este atributo, convertir la cadena de contenido visible en un cierre y ponerla en una cola EventHandler. Aquí es donde entra en juego el constructor de funciones JS.

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);
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top