FlawOpen

flawopen.com/Análisis JSON/JSON.parse() vs eval()

¿JSON.parse() es más seguro que eval()?

Guía de referencia
Respuesta breve

Imagina que la entrada es una nota: JSON.parse() lee los campos de un formulario estructurado, mientras que eval() entrega la nota a un intérprete como instrucciones que debe ejecutar. JSON.parse() sigue la gramática JSON y no ejecuta el JavaScript del texto; los valores resultantes aún deben validarse antes de usarlos.

PELIGROSO — patrón heredado
// No interpretes datos no confiables como código fuente.
const data = eval("(" + untrustedJson + ")");
SEGURO
const data = JSON.parse(untrustedJson);
// Analiza JSON como datos; JSON inválido lanza SyntaxError.

Por qué surge esta pregunta

Antes de que JSON.parse() estuviera ampliamente disponible, parte del código JavaScript usaba eval() para leer JSON porque el texto JSON se solapa con la sintaxis de expresiones de JavaScript. Ese enfoque evalúa un programa JavaScript, así que una entrada controlada por un atacante puede tratarse como código y no limitarse a valores JSON. Usa el analizador JSON para leer JSON.

Qué no protege JSON.parse()

JSON.parse() no valida reglas de negocio, no autoriza acciones ni hace que los valores analizados sean seguros para HTML, SQL, comandos de shell o URL. Valida la forma esperada de los datos y usa codificación de salida adecuada al contexto o APIs parametrizadas. Si pasas un reviver, ese callback proporcionado por la aplicación se ejecuta durante el análisis; mantenlo confiable, sencillo y sin efectos secundarios basados en valores controlados por el atacante.

Preguntas frecuentes

¿JSON.parse() puede ejecutar código de la aplicación?

El texto JSON se analiza como datos, no se ejecuta como JavaScript. Sin embargo, si la aplicación proporciona un reviver, ese callback confiable se invoca para los valores analizados y puede ejecutar código. No permitas que datos controlados por un atacante elijan o construyan la lógica ejecutable del callback.

¿JSON.parse() hace que la entrada sea segura para usar después?

No. Comprueba el valor analizado según el esquema esperado por la aplicación y las reglas de autorización. Usa codificación de salida para HTML y consultas parametrizadas para SQL; analizar no sanea los datos para esos contextos.

Referencias

Véase también Contaminación de prototipos JS: causas y solución ¿lodash.merge() causa contaminación de prototipos? Object.assign() y Prototype Pollution: ¿qué es seguro? ¿JSON.parse() causa contaminación de prototipos?