JSONP: scripts para solicitar datos entre dominios diferentes

Los navegadores y las aplicaciones web disponen de numerosas funciones y medidas para proteger a los usuarios y a sus datos frente a ciberataques. Una de ellas es la llamada same-origin policy (política de seguridad del mismo origen) o SOP, introducida en 1996 por la que fue la empresa creadora del navegador Netscape con la implementación de JavaScrip. Esta normativa prohíbe que tanto lenguajes de programación del lado del cliente (como JavaScript y ActionScript) como lenguajes de hojas de estilo como CSS accedan a objetos (gráficos, vídeos, etc.) procedentes de otro sitio web o URL.

Nota

El origen se define en el URL como una combinación del protocolo (por ejemplo, HTTP o HTTPS), el dominio y el puerto. La SOP solo se cumple si los tres elementos son idénticos, permitiendo así el acceso al script entre sitios web. Una excepción a esta regla son los subdominios, que pueden acceder a objetos de dominios superiores gracias a las propiedades DOM correspondientes.

No obstante, los límites que establece la same-origin policy no benefician a todos los proyectos web y pueden incluso ser un obstáculo en casos concretos. Un ejemplo de ello son las aplicaciones web basadas en una transmisión asíncrona de datos entre el navegador y el servidor (como las basadas en Ajax). Para tales proyectos, son muy demandadas las soluciones que eluden las directrices de la SOP, como el método JSONP, de JSON. A continuación, explicamos esta técnica más en detalle.

¿Qué es JSONP?

JSONP (también escrito JSON-P) es un método que permite enviar datos estructurados en formato JSON entre dominios distintos. Las siglas provienen de JSON (JavaScript Object Notation) with Padding (es decir, “JSON con acolchado”). Para eludir la política de seguridad del mismo origen al solicitar archivos de otros dominios, JSONP no utiliza el objeto XMLHttpRequest como hace el código JSON habitual, sino el elemento script, incluyendo una llamada de función. Al contrario que otros archivos, los scripts pueden ser transferidos también entre dominios sin que la SOP sea infringida por ello.

JSONP fue ideado en 2005 por el desarrollador de software Bob Ippolito y, en los últimos años, ha sido integrado en muchos frameworks de la llamada Web 2.0, como Dojo Toolkit, jQuery o Google Web Toolkit, como alternativa opcional al JSON convencional.

Nota

JSONP es solo un método, de los muchos que existen, para realizar transmisiones de datos entre dominios distintos. Gracias al cross-origin resource sharing (CORS), existe un mecanismo equivalente que no está vinculado a JSON, sino que trabaja con cabeceras HTTP específicos.

¿Cómo funciona JSONP?

JSONP ofrece una solución al obstáculo de la SOP mediante el elemento <script>. En el atributo src de este elemento, pueden escribirse los dominios que se deseen sin que las directrices de la SOP intervengan. Así, mediante este atributo, se pueden indicar también URL que pertenezcan a dominios ajenos y que devuelvan código JSON u otros archivos. En tales casos, el script solo sirve de mensajero para transmitir la solicitud JSONP al servidor web correspondiente, pero no surte ningún efecto por sí mismo. Para que el cliente pueda procesar los datos más adelante, el servidor los empaqueta como parámetros de una función de JavaScript. Esta función está predefinida en el navegador y es transmitida al servidor en la query string (o cadena de consulta, también parte de la solicitud) del URL.

Nota

El formato y el nombre de los parámetros que se indican en la query string para iniciar una solicitud JSONP no están estandarizados. Por ello, difieren según la aplicación web.

El siguiente ejemplo muestra cómo funciona JSONP:

<script type="text/javascript" < codesnippet></script>
src="http://not-origin-url.com/getjson?jsonp=exampleCallback">

Al introducir este sencillo script de JSONP en el código HTML de una página web y ejecutarlo luego con cualquier cliente, se solicitan datos JSON (getjson) del otro dominio (not-origin-url.com). La query string (?jsonp=exampleCallback) comunica al servidor contactado que se trata de una solicitud JSON. Asimismo, se le indica que debe enviar los datos requeridos como parámetros de la función de JavaScript exampleCallback.

A continuación, el servidor genera el código JavaScript correspondiente, incluyendo la información solicitada en forma de parámetro (en nuestro caso, un par nombre-valor) y lo devuelve al cliente:

exampleCallback( {"name":"test", "value":1} );

La llamada de función es entonces ejecutada por el navegador, igual que si estuviese registrada directamente en el código HTML de la página de origen. De esta forma, se permite al navegador procesar los datos del URL externo solicitados.

Nota

Cada solicitud JSONP requiere un único elemento <script>. En este sentido, del lado del cliente se puede escoger entre añadir un nuevo elemento (script element injection) o volver a usar un elemento ya existente.

Este tutorial de YouTube muestra el método JSONP de forma algo más exhaustiva:

¿En qué medida es seguro JSONP?

El uso de JSONP para eludir la SOP es un tema muy controvertido entre los especialistas, sobre todo por el gran riesgo para la seguridad que suponen las solicitudes script. El simple hecho de introducir un componente adicional en los procesos de la página de origen, cuyo sistema de seguridad no se puede modificar, ya puede ser peligroso. Si el servidor contactado tiene puntos débiles que permitan a atacantes realizar JavaScript injections no deseadas (incorporaciones de código JavaScript), el servidor de origen también se expone automáticamente a un riesgo inmediato, sobre todo porque no solo se pueden solicitar documentos JSON (como en el ejemplo), sino todo tipo de datos.

Otros conocidos patrones de ataque que se sirven del método JSONP son los siguientes:

  • RFD (reflected file download): JSONP es vulnerable a los llamados ataques RFD, en los que el cliente o usuario aparentemente descarga datos del dominio final deseado. Lo que ocurre, en realidad, es que se cargan archivos o URL maliciosos, lo cual suele tener su origen en una manipulación de las funciones callback (de devolución de llamada).
  • CSRF/XSRF (cross-site-request-forgery) puesto que el elemento <script> ignora la SOP, una página maliciosa puede solicitar datos de otras aplicaciones web, guardarlos y analizarlos. Si el usuario está registrado en la página atacada, los atacantes podrían acceder a datos privados como, por ejemplo, los datos de inicio de sesión, utilizando las solicitudes entre dominios “falseadas”.

    Si quieres utilizar scripts de JSONP en tu proyecto web, asegúrate de que no solo tu servidor esté protegido contra tales ataques y contra cualquier malware, sino de que también lo estén los de las aplicaciones web con las que contactes. Nunca debe permitirse la incorporación de código JSONP que solicite datos de fuentes poco seguras.

¿Le ha resultado útil este artículo?
Page top