JSONP

Técnica de JavaScript para cargar datos

JSONP , o JSON-P (JSON con relleno), es una técnica histórica de JavaScript<script> para solicitar datos mediante la carga de un elemento, [1] que es un elemento destinado a cargar JavaScript ordinario. Fue propuesto por Bob Ippolito en 2005. [2] JSONP permite compartir datos sin pasar por la política del mismo origen, que no permite ejecutar código JavaScript para leer elementos DOM de medios o datos XMLHttpRequest obtenidos desde fuera del sitio de origen de la página. El sitio de origen se indica mediante una combinación de esquema de URI , nombre de host y número de puerto .

JSONP es vulnerable a que la fuente de datos reemplace la llamada de función inocua con código malicioso, por lo que ha sido reemplazado por el uso compartido de recursos de origen cruzado (disponible desde 2009 [3] ) en las aplicaciones modernas.

Funcionalidad

En general, se permite que el <script>elemento HTML ejecute código JavaScript recuperado de orígenes externos. Sin embargo, los servicios que responden con datos JSON puros no podían compartir datos de orígenes externos antes de la adopción de CORS ( intercambio de recursos entre orígenes ).

Por ejemplo, una solicitud a un servicio externo http://server.example.com/Users/1234puede devolver un registro de una persona llamada Clem en formato JSON. La sintaxis de JSON es coherente con la sintaxis de objetos de JavaScript.

{ "Nombre" : "Clem" , "Id" : 1234 , "Rango" : 7 }      

Sin soporte para CORS, un intento de utilizar los datos en diferentes dominios genera un error de JavaScript.

< script  type = "application/javascript"  src = "http://server.example.com/Users/1234" > </ script >

El navegador descargará el <script>archivo, evaluará su contenido, malinterpretará los datos JSON sin procesar como un bloque y generará un error de sintaxis. Incluso si los datos se interpretaran como un literal de objeto de JavaScript, no se podría acceder a ellos mediante JavaScript que se ejecuta en el navegador, ya que sin una asignación de variable, los literales de objeto son inaccesibles.

En el patrón de uso de JSONP, la solicitud de URL a la que apunta el srcatributo en el <script>elemento devuelve datos JSON, con código JavaScript (normalmente una llamada a una función) envuelto alrededor de ellos. Esta "carga útil envuelta" es luego interpretada por el navegador. De esta manera, una función que ya está definida en el entorno de JavaScript puede manipular los datos JSON. A continuación, se muestra una solicitud y una respuesta JSONP típicas.

La llamada de función a parseResponse() es la "P" de JSONP, el "relleno" o "prefijo" alrededor del JSON puro. [4] Para que JSONP funcione, un servidor debe responder con una respuesta que incluya la función JSONP. JSONP no funciona con resultados con formato JSON. La invocación de la función JSONP que se envía de vuelta y la carga útil que recibe la función deben ser acordadas por el cliente y el servidor. Por convención, el servidor que proporciona los datos JSON ofrece al sitio web solicitante que nombre la función JSONP, generalmente usando el nombre jsonp o callback como el parámetro de cadena de consulta nombrado, en su solicitud al servidor: <script src="http://server.example.com/Users/1234?callback=parseResponse"></script>.

En este ejemplo, la carga útil recibida sería:

parseResponse ({ "Nombre" : "Clem" , "Id" : 1234 , "Rango" : 7 });     

Inyección de elementos de script

JSONP solo tiene sentido cuando se utiliza con un elemento de script. Para cada nueva solicitud JSONP, el navegador debe agregar un nuevo <script>elemento o reutilizar uno existente. La primera opción (agregar un nuevo elemento de script) se realiza mediante manipulación dinámica del DOM y se conoce como inyección de elemento de script . El <script>elemento se inyecta en el DOM HTML, con la URL del punto final JSONP deseado establecido como el atributo "src". Esta inyección dinámica de elementos de script generalmente se realiza mediante una biblioteca auxiliar de JavaScript. jQuery y otros marcos tienen funciones auxiliares de JSONP; también hay opciones independientes.

Un ejemplo de uso de jQuery para inyectar dinámicamente un elemento de script para una llamada JSONP se ve así:

$ . getScript ( "http://servidor.ejemplo.com/Usuarios/192.168.73.96?callback=parseResponse" );

Una vez que se inyecta el elemento, el navegador lo evalúa y realiza una operación HTTP GET en la URL de origen, recuperando el contenido. Luego, el navegador evalúa la carga útil devuelta como JavaScript. Esto suele ser una invocación de función. De esa manera, el uso de JSONP puede permitir que las páginas del navegador eludan la política del mismo origen a través de la inyección de elementos de script. [5]

El script se ejecuta dentro del ámbito de la página incluida y, como tal, sigue estando sujeto a restricciones entre dominios en relación con el dominio de la página incluida. Esto significa que una página web no puede, por ejemplo, cargar una biblioteca alojada en otro sitio a través de JSONP y luego realizar solicitudes XMLHttpRequest a ese sitio (a menos que se admita el uso compartido de recursos entre orígenes (CORS)), aunque se podría utilizar una biblioteca de este tipo para realizar solicitudes XMLHttpRequest a un sitio propio.

Preocupaciones de seguridad

Código de terceros que no es de confianza

La inclusión de elementos de script de servidores remotos permite que estos últimos inyecten cualquier contenido en un sitio web. Si los servidores remotos tienen vulnerabilidades que permiten la inyección de JavaScript, la página servida desde el servidor original está expuesta a un mayor riesgo. Si un atacante puede inyectar cualquier JavaScript en la página web original, entonces ese código puede recuperar JavaScript adicional de cualquier dominio, evadiendo la política del mismo origen . [6] El encabezado HTTP de la política de seguridad de contenido permite que los sitios web indiquen a los navegadores web de qué dominio se pueden incluir los scripts.

En 2011 se realizó un esfuerzo para definir una definición de subconjunto estricto más segura para JSONP [1] que los navegadores podrían aplicar en solicitudes de script con un tipo MIME específico como "application/json-p". Si la respuesta no se analizaba como JSONP estricto, el navegador podría generar un error o simplemente ignorar la respuesta completa. Sin embargo, este enfoque se abandonó a favor de CORS y el tipo MIME correcto para JSONP sigue siendo [7]application/javascript .

Diferencias en los espacios en blanco

JSONP conllevaba los mismos problemas que resolver JSON con eval(): ambos interpretan el texto JSON como JavaScript, lo que implicaba diferencias en el manejo de U+2028 ( Separador de línea ) y U+029 ( Separador de párrafo ) del JSON propiamente dicho. Esto hacía que algunas cadenas JSON no fueran legales en JSONP; los servidores que servían JSONP tenían que escapar estos caracteres antes de la transmisión. [8] Este problema se ha corregido ahora en ES2019. [9]

Manipulación de nombres de devolución de llamada y ataque de descarga de archivos reflejados

Se pueden usar nombres de devolución de llamada no sanitizados para pasar datos maliciosos a los clientes, eludiendo las restricciones asociadas con application/jsonel tipo de contenido, como se demostró en el ataque de descarga de archivos reflejados (RFD) de 2014. [10]

Los puntos finales JSONP inseguros también pueden ser inyectados con datos maliciosos. [11]

Falsificación de solicitudes entre sitios

Las implementaciones ingenuas de JSONP están sujetas a ataques de falsificación de solicitud entre sitios (CSRF o XSRF). [12] Debido a que el elemento HTML <script>no respeta la política del mismo origen en las implementaciones del navegador web, una página maliciosa puede solicitar y obtener datos JSON que pertenecen a otro sitio. Esto permitirá que los datos codificados en JSON se evalúen en el contexto de la página maliciosa, posiblemente divulgando contraseñas u otros datos confidenciales si el usuario está conectado actualmente al otro sitio.

Rosetta Flash

Rosetta Flash es una técnica de explotación que permite a un atacante explotar servidores con un punto final JSONP vulnerable haciendo que Adobe Flash Player crea que un subprograma Flash especificado por el atacante se originó en el servidor vulnerable. Flash Player implementa una política del mismo origen que permite realizar solicitudes (con cookies) y recibir respuestas del sitio de alojamiento. El subprograma puede luego enviar los datos recuperados de vuelta al atacante. Este es un exploit de origen cruzado con un impacto similar a la incrustación de un subprograma Flash arbitrario en el dominio vulnerable. El exploit utiliza una carga útil de ActionScript compilada en un archivo SWF compuesto completamente de caracteres alfanuméricos mediante la elaboración de un flujo zlib con un encabezado particular y bloques DEFLATE con codificación Huffman ad-hoc . El archivo SWF alfanumérico resultante se utiliza luego como parámetro de devolución de llamada de una llamada JSONP. Sitios de alto perfil como Google, YouTube, Twitter, Yahoo!, Yandex, LinkedIn, eBay, GitHub, Instagram y Tumblr fueron vulnerables hasta julio de 2014. [13] Esta vulnerabilidad fue descubierta inicialmente por Erling y Alok Menghrajani, con una presentación pública en una conferencia de seguridad. La explotación de la vulnerabilidad fue posteriormente mejorada por Gábor Molnár. El ingeniero de seguridad de Google Michele Spagnuolo acuñó el término [14] y tiene CVE - 2014-4671 [15] y CVE- 2014-5333. [16] La versión 14.0.0.145 de Adobe Flash Player, lanzada el 8 de julio de 2014, introdujo una validación más fuerte de los archivos Flash, [17] y en la versión 14.0.0.176, lanzada el 12 de agosto de 2014, finalizó la corrección, [18] impidiendo que este exploit funcione.

Antes de la solución de Adobe, los sitios web podían protegerse anteponiendo un comentario de JavaScript vacío (/**/) o incluso solo una nueva línea como los primeros bytes de la respuesta JSONP.

Historia

En julio de 2005, George Jempty sugirió que se antepusiera una asignación de variable opcional a JSON. [19] [20] La propuesta original para JSONP, donde el relleno es una función de devolución de llamada, parece haber sido realizada por Bob Ippolito en diciembre de 2005 [21] y ahora es utilizada por muchas aplicaciones Web 2.0 como Dojo Toolkit y Google Web Toolkit .

Véase también

Referencias

  1. ^ ab "Ajax entre dominios más seguro con JSON-P/JSONP". JSON-P.org . Archivado desde el original el 4 de marzo de 2016 . Consultado el 30 de octubre de 2011 .
  2. ^ Ippolito, Bob (5 de diciembre de 2005). «JSON remoto: JSONP». Bob Ippolito sobre Haskell, Python, Erlang, JavaScript, etc. Archivado desde el original el 8 de junio de 2012. Consultado el 10 de febrero de 2017 .
  3. ^ "Intercambio de recursos entre orígenes". ¿Puedo utilizar... ? Consultado el 4 de mayo de 2020 .
  4. ^ "Conjunto de resultados RDF experimentales para traductor JSON". Archivado desde el original el 15 de noviembre de 2014. Consultado el 20 de febrero de 2012 .
  5. ^ "Entonces, ¿cómo funciona realmente JSONP? Algunos ejemplos sencillos". Jason Schock . 5 de febrero de 2013. Archivado desde el original el 26 de diciembre de 2021 . Consultado el 26 de diciembre de 2021 .
  6. ^ Ben Hayak (17 de octubre de 2014). "Ejecución del método del mismo origen" (PDF) . Consultado el 22 de octubre de 2014 .
  7. ^ Grey, Eli (27 de junio de 2010). "¿Es seguro proporcionar JSONP?". stackoverflow.com . Consultado el 7 de septiembre de 2012 .
  8. ^ "JSON: El subconjunto de JavaScript que no existe". Magnus Holm. Archivado desde el original el 13 de mayo de 2012. Consultado el 16 de mayo de 2011 .
  9. ^ "Subsumir JSON (también conocido como JSON ⊂ ECMAScript)". GitHub . 24 de octubre de 2022 . Consultado el 24 de octubre de 2022 .
  10. ^ Oren Hafif (2014). "Descarga de archivos reflejada: un nuevo vector de ataque web". TrustWave . Consultado el 25 de marzo de 2015 .
  11. ^ "Inyección práctica de JSONP". 18 de enero de 2017.
  12. ^ Grossman, Jeremiah (27 de enero de 2006). "Técnicas avanzadas de ataque web con Gmail" . Consultado el 3 de julio de 2009 .
  13. ^ Michele, Spagnuolo. "Abusing JSONP with Rosetta Flash". Archivado desde el original el 21 de julio de 2014. Consultado el 20 de julio de 2014 .
  14. ^ "Google: lista de vulnerabilidades de software descubiertas o corregidas por los empleados de Google" . Consultado el 29 de julio de 2014 .
  15. ^ "MITRE: CVE-2014-4671" . Consultado el 29 de julio de 2014 .
  16. ^ "MITRE: CVE-2014-5333" . Consultado el 21 de agosto de 2014 .
  17. ^ "Boletín de seguridad de Adobe APSB14-17" . Consultado el 29 de julio de 2014 .
  18. ^ "Boletín de seguridad de Adobe APSB14-18" . Consultado el 21 de agosto de 2014 .
  19. ^ "eval'ing JSON". 19 de julio de 2005. Archivado desde el original el 12 de febrero de 2006.
  20. ^ "json: Message: Re: Comments". 17 de agosto de 2005. Archivado desde el original el 22 de julio de 2012.
  21. ^ "JSON remoto - JSONP". de __future__ import * . Bob.pythonmac.org. 5 de diciembre de 2005. Archivado desde el original el 4 de diciembre de 2009 . Consultado el 8 de septiembre de 2008 .
  • El filtro del lado del servidor envuelve cualquier respuesta en una devolución de llamada jsonp (hecho con el código fuente jsonp-java)
  • Posibles problemas de seguridad relacionados con JSON
  • Fuente de datos JSONP para dominios remotos
Obtenido de "https://es.wikipedia.org/w/index.php?title=JSONP&oldid=1247044273"