¿Por qué Google antepone while(1);
sus respuestas JSON (privadas)?
Por ejemplo, aquí hay una respuesta al activar y desactivar un calendario en Google Calendar :
while (1);
[
['u', [
['smsSentFlag', 'false'],
['hideInvitations', 'false'],
['remindOnRespondedEventsOnly', 'true'],
['hideInvitations_remindOnRespondedEventsOnly', 'false_true'],
['Calendar ID stripped for privacy', 'false'],
['smsVerifiedFlag', 'true']
]]
]
Supongo que esto es para evitar que las personas hagan algo eval()
al respecto, pero todo lo que realmente tendría que hacer es reemplazar el while
y luego estaría listo. Supongo que la prevención de evaluación es garantizar que las personas escriban un código de análisis JSON seguro.
También he visto esto usado en un par de otros lugares, pero mucho más con Google (Correo, Calendario, Contactos, etc.) Curiosamente, Google Docs comienza en su &&&START&&&
lugar, y Google Contactos parece comenzar con while(1); &&&START&&&
.
¿Que está pasando aqui?
javascript
json
ajax
security
Encadenar
fuente
fuente
)]}'
ahora en lugar dewhile(1);
? ¿Serían las respuestas las mismas?)]}'
también puede ser para guardar bytes, como Facebook usadofor(;;);
que ahorra un byte :)JSON hijacking
Respuestas:
Impide el secuestro de JSON , un importante problema de seguridad de JSON que se corrige formalmente en todos los principales navegadores desde 2011 con ECMAScript 5.
Ejemplo contribuido: digamos que Google tiene una URL como la
mail.google.com/json?action=inbox
que devuelve los primeros 50 mensajes de su bandeja de entrada en formato JSON. Los sitios web malvados en otros dominios no pueden realizar solicitudes AJAX para obtener estos datos debido a la política del mismo origen, pero pueden incluir la URL a través de una<script>
etiqueta. La URL se visita con sus cookies, y al anular el constructor de matriz global o los métodos de acceso pueden tener un método llamado cada vez que se establece un atributo de objeto (matriz o hash), lo que les permite leer el contenido JSON.El
while(1);
o&&&BLAH&&&
previene esto: una petición AJAX amail.google.com
tendrá acceso total al contenido del texto, y puede despojar a la basura. Pero una<script>
inserción de etiqueta ejecuta ciegamente el JavaScript sin ningún procesamiento, lo que resulta en un bucle infinito o un error de sintaxis.Esto no aborda el problema de la falsificación de solicitudes entre sitios .
fuente
for(;;);
el mismo trabajo? He visto esto en las respuestas ajax de Facebook.Impide la divulgación de la respuesta a través del secuestro de JSON.
En teoría, el contenido de las respuestas HTTP está protegido por la Política del mismo origen: las páginas de un dominio no pueden obtener ninguna información de las páginas del otro dominio (a menos que se permita explícitamente).
Un atacante puede solicitar páginas en otros dominios en su nombre, por ejemplo, usando una etiqueta
<script src=...>
o<img>
, pero no puede obtener ninguna información sobre el resultado (encabezados, contenido).Por lo tanto, si visita la página de un atacante, no podrá leer su correo electrónico de gmail.com.
Excepto que cuando se usa una etiqueta de script para solicitar contenido JSON, el JSON se ejecuta como Javascript en el entorno controlado de un atacante. Si el atacante puede reemplazar el constructor Array u Object o algún otro método utilizado durante la construcción del objeto, cualquier cosa en el JSON pasaría por el código del atacante y se divulgaría.
Tenga en cuenta que esto sucede en el momento en que JSON se ejecuta como Javascript, no en el momento en que se analiza.
Hay múltiples contramedidas:
Asegurarse de que el JSON nunca se ejecute
Al colocar una
while(1);
declaración antes de los datos JSON, Google se asegura de que los datos JSON nunca se ejecuten como Javascript.Solo una página legítima podría obtener todo el contenido, eliminar el contenido
while(1);
y analizar el resto como JSON.Cosas como
for(;;);
se han visto en Facebook, por ejemplo, con los mismos resultados.Asegurarse de que el JSON no sea Javascript válido
Del mismo modo, agregar tokens no válidos antes del JSON, como
&&&START&&&
, asegura que nunca se ejecute.Siempre devuelva JSON con un objeto en el exterior
Esta es una
OWASP
forma recomendada de proteger contra el secuestro de JSON y es la menos intrusiva.Similar a las contramedidas anteriores, se asegura de que el JSON nunca se ejecute como Javascript.
Un objeto JSON válido, cuando no está encerrado por nada, no es válido en Javascript:
Sin embargo, esto es válido JSON:
Por lo tanto, asegúrese de que siempre devuelve un Objeto en el nivel superior de la respuesta, asegúrese de que el JSON no sea Javascript válido, mientras siga siendo JSON válido.
Como señaló @hvd en los comentarios, el objeto vacío
{}
es Javascript válido, y saber que el objeto está vacío puede ser una información valiosa.Comparación de los métodos anteriores.
La forma OWASP es menos intrusiva, ya que no necesita cambios en la biblioteca del cliente y transfiere JSON válidos. Sin embargo, no está claro si los errores pasados o futuros del navegador podrían vencer esto. Como señaló @oriadam, no está claro si los datos podrían filtrarse en un error de análisis mediante un tratamiento de errores o no (por ejemplo, window.onerror).
La forma en que Google requiere la biblioteca del cliente para que sea compatible con la deserialización automática y puede considerarse más segura sobre los errores del navegador.
Ambos métodos requieren cambios en el lado del servidor para evitar que los desarrolladores envíen accidentalmente JSON vulnerables.
fuente
script
etiqueta oeval
función. Las llaves{}
se pueden interpretar como un bloque de código o un objeto literal, y por sí mismo, JavaScript prefiere el primero. Como bloque de código es, por supuesto, inválido. Según esta lógica, no puedo ver ningún cambio previsible en el comportamiento futuro del navegador.window.onerror
) No estoy seguro de cuál es el comportamiento de losonerror
errores de sintaxis. Supongo que Google tampoco estaba seguro.{}
), que también es un bloque vacío válido. Si saber que el objeto está vacío puede ser información valiosa, esto podría ser explotable.Esto es para garantizar que algún otro sitio no pueda hacer trucos desagradables para intentar robar sus datos. Por ejemplo, al reemplazar el constructor de matriz , y luego incluir esta URL JSON a través de una
<script>
etiqueta, un sitio malicioso de terceros podría robar los datos de la respuesta JSON. Al poner unwhile(1);
al principio, el script se bloqueará en su lugar.Una solicitud del mismo sitio usando XHR y un analizador JSON separado, por otro lado, puede ignorar fácilmente el
while(1);
prefijo.fuente
<script>
elemento antiguo simple , no un XHR.<script>
etiquetaEso sería para dificultar que un tercero inserte la respuesta JSON en un documento HTML con la
<script>
etiqueta. Recuerde que la<script>
etiqueta está exenta de la Política del mismo origen .fuente
Object
yArray
, ejecutar una respuesta JSON válida como si fuera JavaScript sería totalmente inocuo en todas las circunstancias. Sí,while(1);
evita que la respuesta se ejecute como JavaScript si está dirigida por una<script>
etiqueta, pero su respuesta no explica por qué es necesario.Nota : a partir de 2019, muchas de las viejas vulnerabilidades que conducen a las medidas preventivas discutidas en esta pregunta ya no son un problema en los navegadores modernos. Dejaré la respuesta a continuación como una curiosidad histórica, pero realmente todo el tema ha cambiado radicalmente desde 2010 (!!) cuando se preguntó esto.
Impide que se use como objetivo de una
<script>
etiqueta simple . (Bueno, no lo previene, pero lo hace desagradable.) De esa manera, los malos no pueden simplemente poner esa etiqueta de script en su propio sitio y confiar en una sesión activa para que sea posible recuperar su contenido.editar : tenga en cuenta el comentario (y otras respuestas). La cuestión tiene que ver con subvertido incorporado de instalaciones, específicamente las
Object
yArray
constructores. Esos pueden ser alterados de tal manera que JSON, de otra manera inocuo, cuando se analiza, podría desencadenar el código del atacante.fuente
Object
yArray
, ejecutar una respuesta JSON válida como si fuera JavaScript sería totalmente inocuo en todas las circunstancias. Sí,while(1);
evita que la respuesta se ejecute como JavaScript si está dirigida por una<script>
etiqueta, pero su respuesta no explica por qué es necesario.Dado que la
<script>
etiqueta está exenta de la Política del mismo origen, que es una necesidad de seguridad en el mundo web,while(1)
cuando se agrega a la respuesta JSON evita el mal uso de la misma en la<script>
etiqueta.fuente
Referencia: Libro de cocina de pruebas de seguridad web: técnicas sistemáticas para encontrar problemas rápidamente
fuente