¿Qué hace una respuesta de llamada Ajax como ‘for (;;); {json data} ‘¿quiere decir?

Posible duplicado:
¿Por qué la gente pone código como “arrojar 1; “y” para (;;); “delante de las respuestas json?

Encontré este tipo de syntax que se usa en Facebook para las llamadas Ajax. Estoy confundido en el for (;;); parte en el comienzo de la respuesta. ¿Para qué se usa esto?

Esta es la llamada y respuesta:

 GET http://0.131.channel.facebook.com/x/1476579705/51033089/false/p_1524926084=0 

Respuesta:

 for (;;);{"t":"continue"} 

Facebook tiene una tonelada de desarrolladores trabajando internamente en muchos proyectos, y es muy común que alguien cometa un pequeño error; ya sea algo tan simple y serio como no escaparse de los datos insertados en una plantilla HTML o SQL o algo tan intrincado y sutil como usar eval (a veces ineficaz y posiblemente inseguro) o JSON.parse (una extensión compatible pero no universalmente implementada) de un decodificador JSON “bien conocido”, es importante encontrar formas de aplicar fácilmente las mejores prácticas en esta población de desarrolladores.

Para hacer frente a este desafío, Facebook recientemente ha estado trabajando con proyectos internos diseñados para hacer cumplir estas mejores prácticas, y para ser sincero, la única explicación que realmente tiene sentido para este caso específico es justamente eso: alguien decidió internamente que todo JSON el análisis debe pasar por una única implementación en su biblioteca principal, y la mejor manera de hacer cumplir eso es que cada respuesta de API obtenga for(;;); tachado automáticamente en el frente.

Al hacerlo, un desarrollador no puede ser “perezoso”: se darán cuenta de inmediato si usan eval() , se preguntan qué pasa, y luego se dan cuenta de su error y usan la API JSON aprobada.

Las otras respuestas proporcionadas parecen todas caer en una de dos categorías:

  1. malentendido JSONP, o
  2. malentendido “secuestro de JSON”.

Aquellos en la primera categoría confían en la idea de que un atacante puede de alguna manera hacer una solicitud “usando JSONP” a una API que no lo admite. JSONP es un protocolo que debe ser admitido tanto en el servidor como en el cliente: requiere que el servidor devuelva algo similar a myFunction({"t":"continue"}) modo que el resultado se pase a una función local. No puedes simplemente “usar JSONP” por accidente.

Aquellos en la segunda categoría citan una vulnerabilidad muy real que ha sido descrita permitiendo una falsificación de solicitudes entre sitios a través de tags a API que no usan JSONP (como esta), lo que permite una forma de “secuestro JSON”. Esto se hace cambiando el constructor Array / Object, que permite acceder a la información que se devuelve desde el servidor sin una función de ajuste.

Sin embargo, eso simplemente no es posible en este caso: la razón por la que funciona en absoluto es que una matriz vacía (un resultado posible de muchas API JSON, como el famoso ejemplo de Gmail) es una statement de expresión válida, lo que no es cierto para un objeto desnudo

De hecho, la syntax de los objetos definidos por JSON (que incluye comillas alrededor de los nombres de campo, como se ve en este ejemplo) entra en conflicto con la syntax de los bloques y, por lo tanto, no se puede utilizar en el nivel superior de un script.

 js> {"t":"continue"} typein:2: SyntaxError: invalid label: typein:2: {"t":"continue"} typein:2: ....^ 

Para que este ejemplo sea explotable mediante la reasignación de constructores de Object (), requeriría que la API haya devuelto el objeto dentro de un conjunto de paréntesis, lo que lo convierte en JavaScript válido (pero luego no es JSON válido).

 js> ({"t":"continue"}) [object Object] 

Ahora, podría ser que esto for(;;); el truco del prefijo solo aparece “accidentalmente” en este ejemplo, y de hecho lo están devolviendo otras API internas de Facebook que devuelven matrices; pero en este caso eso debería ser notado, ya que esa sería la causa “real” de por qué for(;;); está apareciendo en este fragmento específico.

Sospecho que la razón principal por la que está ahí es el control. Te obliga a recuperar los datos a través de Ajax, no a través de JSON-P o similar (que usa tags de script , por lo que fallaría porque ese ciclo for infinito), y así garantiza que la política de mismo origen se active. Esto les permite controlar qué documentos pueden emitir llamadas a la API; específicamente, solo documentos que tienen el mismo origen que esa llamada API, o aquellos a los que Facebook otorga acceso específicamente a través de CORS (en navegadores que admiten CORS). Por lo tanto, debe solicitar los datos a través de un mecanismo donde el navegador aplicará el SOP, y debe conocer ese prefacio y eliminarlo antes de deserializar los datos.

Así que sí, se trata de controlar el acceso (útil) a esa información.

Bueno, el for(;;); es un bucle infinito (puede usar la consola de JavaScript de Chrome para ejecutar ese código en una pestaña, si lo desea, y luego ver cómo el uso de la CPU en el administrador de tareas se dispara hasta que el navegador cancela la pestaña).

Así que sospecho que tal vez se está poniendo allí para frustrar a cualquiera que intente analizar la respuesta utilizando eval o cualquier otra técnica que ejecute los datos devueltos.

Para explicarlo aún más, solía ser bastante común analizar un poco de datos formateados en JSON utilizando la función eval() JavaScript, haciendo algo como:

var parsedJson = eval('(' + jsonString + ')') ;

… esto se considera inseguro, sin embargo, como por alguna razón los datos formateados en JSON contienen código JavaScript ejecutable en lugar de (o además de) los datos formateados en JSON, entonces el eval() ejecutará ese código. Esto significa que si está hablando con un servidor que no es de confianza, o si alguien pone en peligro un servidor confiable, entonces pueden ejecutar código arbitrario en su página.

Debido a esto, el uso de cosas como eval() para analizar datos con formato JSON generalmente no está bien visto, y el uso for(;;); La statement en Facebook JSON evitará que las personas analicen los datos de esa manera. Cualquiera que intente obtendrá un bucle infinito. En esencia, es como si Facebook estuviera tratando de hacer cumplir que las personas trabajen con su API de una manera que no los deje vulnerables a exploits futuros que intenten apropiarse de la API de Facebook para usarla como vector.

Llego un poco tarde y TJ básicamente ha resuelto el misterio, pero pensé que compartiría un excelente artículo sobre este tema en particular que tiene buenos ejemplos y proporciona una visión más profunda de este mecanismo.

Estos bucles infinitos son una contramedida contra el “secuestro de Javascript”, un tipo de ataque que llamó la atención del público con un ataque a Gmail que fue publicado por Jeremiah Grossman .

La idea es tan simple como hermosa: muchos usuarios tienden a iniciar sesión permanentemente en Gmail o Facebook. Entonces, lo que haces es configurar un sitio y en el Javascript de tu sitio malicioso anulas el objeto o el constructor de la matriz:

 function Object() { //Make an Ajax request to your malicious site exposing the object data } 

luego incluye una etiqueta en ese sitio, como

  

Y finalmente puede leer todo sobre los objetos JSON en los registros de su servidor malicioso.

Como prometió, el enlace al periódico .

Esto parece un truco para evitar un ataque CSRF . Existen formas específicas de navegar en la creación de objetos, de manera que un sitio web malicioso podría usarlo primero, y luego tener lo siguiente:

  

Si no hubiera un bucle infinito antes del JSON, se crearía un objeto, ya que JSON puede eval() como javascript y los enganches lo detectarían y detectarían los miembros del objeto.

Ahora, si visita ese sitio desde un navegador, mientras está conectado a Facebook, puede obtener sus datos como si fuera usted, y luego enviarlos de vuelta a su propio servidor, por ejemplo, mediante una publicación AJAX o javascript.