Los na­ve­ga­do­res y las apli­ca­cio­nes web disponen de numerosas funciones y medidas para proteger a los usuarios y a sus datos frente a ci­ber­ata­ques. Una de ellas es la llamada same-origin policy (política de seguridad del mismo origen) o SOP, in­tro­du­ci­da en 1996 por la que fue la empresa creadora del navegador Netscape con la im­ple­me­n­ta­ción de JavaScrip. Esta normativa prohíbe que tanto lenguajes de pro­gra­ma­ción del lado del cliente (como Ja­va­S­cri­pt y Ac­tio­n­S­cri­pt) como lenguajes de hojas de estilo como CSS accedan a objetos (gráficos, vídeos, etc.) pro­ce­de­n­tes de otro sitio web o URL.

Nota

El origen se define en el URL como una co­m­bi­na­ció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, pe­r­mi­tie­n­do así el acceso al script entre sitios web. Una excepción a esta regla son los su­b­do­mi­nios, que pueden acceder a objetos de dominios su­pe­rio­res gracias a las pro­pie­da­des DOM co­rre­s­po­n­die­n­tes.

No obstante, los límites que establece la same-origin policy no be­ne­fi­cian a todos los proyectos web y pueden incluso ser un obstáculo en casos concretos. Un ejemplo de ello son las apli­ca­cio­nes web basadas en una tra­n­s­mi­sión asíncrona de datos entre el navegador y el servidor (como las basadas en Ajax). Para tales proyectos, son muy de­ma­n­da­das las so­lu­cio­nes que eluden las di­re­c­tri­ces de la SOP, como el método JSONP, de JSON. A co­n­ti­nua­ción, ex­pli­ca­mos esta técnica más en detalle.

¿Qué es JSONP?

JSONP (también escrito JSON-P) es un método que permite enviar datos es­tru­c­tu­ra­dos en formato JSON entre dominios distintos. Las siglas provienen de JSON (Ja­va­S­cri­pt 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 XM­LH­t­t­pRe­que­st como hace el código JSON habitual, sino el elemento script, in­clu­ye­n­do una llamada de función. Al contrario que otros archivos, los scripts pueden ser tra­n­s­fe­ri­dos también entre dominios sin que la SOP sea in­fri­n­gi­da por ello.

JSONP fue ideado en 2005 por el de­sa­rro­lla­dor de software Bob Ippolito y, en los últimos años, ha sido integrado en muchos fra­me­wo­r­ks de la llamada Web 2.0, como Dojo Toolkit, jQuery o Google Web Toolkit, como al­te­r­na­ti­va opcional al JSON co­n­ve­n­cio­nal.

Nota

JSONP es solo un método, de los muchos que existen, para realizar tra­n­s­mi­sio­nes de datos entre dominios distintos. Gracias al cross-origin resource sharing (CORS), existe un mecanismo equi­va­le­n­te que no está vinculado a JSON, sino que trabaja con cabeceras HTTP es­pe­cí­fi­cos.

¿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 es­cri­bi­r­se los dominios que se deseen sin que las di­re­c­tri­ces de la SOP in­te­r­ve­n­gan. Así, mediante este atributo, se pueden indicar también URL que pe­r­te­ne­z­can a dominios ajenos y que devuelvan código JSON u otros archivos. En tales casos, el script solo sirve de mensajero para tra­n­s­mi­tir la solicitud JSONP al servidor web co­rre­s­po­n­die­n­te, 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 pa­rá­me­tros de una función de Ja­va­S­cri­pt. Esta función está pre­de­fi­ni­da en el navegador y es tra­n­s­mi­ti­da 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 pa­rá­me­tros que se indican en la query string para iniciar una solicitud JSONP no están es­ta­n­da­ri­za­dos. Por ello, difieren según la apli­ca­ció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 in­tro­du­cir este sencillo script de JSONP en el código HTML de una página web y eje­cu­tar­lo luego con cualquier cliente, se solicitan datos JSON (getjson) del otro dominio (not-origin-url.com). La query string (?jsonp=exam­ple­Ca­ll­ba­ck) comunica al servidor co­n­ta­c­ta­do que se trata de una solicitud JSON. Asimismo, se le indica que debe enviar los datos re­que­ri­dos como pa­rá­me­tros de la función de Ja­va­S­cri­pt exam­ple­Ca­ll­back.

A co­n­ti­nua­ción, el servidor genera el código Ja­va­S­cri­pt co­rre­s­po­n­die­n­te, in­clu­ye­n­do la in­fo­r­ma­ción so­li­ci­ta­da 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 re­gi­s­tra­da di­re­c­ta­me­n­te en el código HTML de la página de origen. De esta forma, se permite al navegador procesar los datos del URL externo so­li­ci­ta­dos.

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 exhau­s­ti­va:

¿En qué medida es seguro JSONP?

El uso de JSONP para eludir la SOP es un tema muy co­n­tro­ve­r­ti­do entre los es­pe­cia­li­s­tas, sobre todo por el gran riesgo para la seguridad que suponen las so­li­ci­tu­des script. El simple hecho de in­tro­du­cir un co­m­po­ne­n­te 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 co­n­ta­c­ta­do tiene puntos débiles que permitan a atacantes realizar Ja­va­S­cri­pt in­je­c­tio­ns no deseadas (in­co­r­po­ra­cio­nes de código Ja­va­S­cri­pt), el servidor de origen también se expone au­to­má­ti­ca­me­n­te a un riesgo inmediato, sobre todo porque no solo se pueden solicitar do­cu­me­n­tos JSON (como en el ejemplo), sino todo tipo de datos.

Otros conocidos patrones de ataque que se sirven del método JSONP son los si­guie­n­tes:

  • RFD (reflected file download): JSONP es vu­l­ne­ra­ble a los llamados ataques RFD, en los que el cliente o usuario apa­re­n­te­me­n­te descarga datos del dominio final deseado. Lo que ocurre, en realidad, es que se cargan archivos o URL ma­li­cio­sos, lo cual suele tener su origen en una ma­ni­pu­la­ción de las funciones callback (de de­vo­lu­ció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 apli­ca­cio­nes web, gua­r­dar­los y ana­li­zar­los. Si el usuario está re­gi­s­tra­do en la página atacada, los atacantes podrían acceder a datos privados como, por ejemplo, los datos de inicio de sesión, uti­li­za­n­do las so­li­ci­tu­des 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 apli­ca­cio­nes web con las que contactes. Nunca debe pe­r­mi­ti­r­se la in­co­r­po­ra­ción de código JSONP que solicite datos de fuentes poco seguras.

Ir al menú principal