Los navegadores son las aplicaciones más usadas por los usuarios a causa del desplazamiento del escritorio "a la nube" y por la grandes posibilidades que abarcan. La creciente complejidad del navegador ha permitido potenciar sus funcionalidades y (en consecuencia)
aumentar los problemas de seguridad y su criticidad.
Pero además,
ha exigido nuevos métodos de intercambio de información y protocolos.
Veamos algunos.
En el desarrollo web actual se pueden llegar a realizar múltiples peticiones AJAX a distintos componentes de la aplicación, como pueden ser gráficas que reciben JSON o un componente de login externo
. Puesto que SOP puede llegar
a ser una política demasiado restrictiva para satisfacer esta demanda en algunos casos, la tecnología CORS nace como solución para compartir recursos con otros dominios sin llegar a poner en peligro la integridad de la información que manejan... siempre y cuando se implementen correctamente.

Usando CORS, se pueden realizar peticiones a otros dominios, como b.com. Fuente: http://linuxism.tistory.com/732
Cross Origin Sharing Resource (CORS)
permite al navegador realizar una petición web a otro dominio que no cumpla con la política SOP siempre y cuando el dominio destino agregue la cabecera
Access-Control-Allow-Origin
, especificando a qué orígenes permite la petición. Por ejemplo:
Access-Control-Allow-Origin: http://www.dominio-tercero.com
Con apenas unas líneas, el navegador será capaz de realizar una petición XMLHttpRequest. Se observa cómo el flag
Access-Control entra en juego:

Código JavaScript para realizar una petición XMLHttpRequest
En caso de que el servidor no responda con la cabecera
Access-Control-Allow-Origin esperada, el navegador impedirá realizar la petición lanzando una excepción:

Chrome rechaza la petición XMLHttpRequest por no incluir el dominio destino la cabecera Access-Control-Allow-Origin
Por el contrario, si contiene la cabecera Access-Control-Allow-Origin, el código JavaScript obtendrá la respuesta en HTML o XML dependiendo del formato y continuará su ejecución.
Como medida de seguridad, también es destacable que la cookie de sesión no se incluirá en la petición si el servidor no añade explícitamente la cabecera
Access-Control-Allow-Credentials. De este modo,
a menos que el servidor indique expresamente que quiere compartir sus recursos, el navegador no lo permitirá. Por otro lado los dominios que implementen esta funcionalidad añadiendo la cabecera Access-Control-Allow-Origin
, permitirán al atacante leer el contenido de la página (lo que implica que además podrá evadir los Anti-Forgery Token que pueda contener la web).
Un posible ataque
Un escenario de ataque en el que el atacante obtuviese el contenido de una web interna y lo reportase, sería el siguiente:

Diagrama funcional de un posible ataque. Fuente: http://application-aegis.blogspot.com.es/2012/06/html5-feature-cross-origin-resource.html
El escenario consta de un servidor web interno que tiene habilitada la cabecera Access-Control-Allow-Origin
a cualquier dominio representado con el asterisco (*), y una web atacante a la que el usuario accederá.
Una vez el usuario accede al sitio web del atacante, este incluirá una porción de código JavaScript que se ejecutará y provocará una petición
XMLHttpRequest al servidor interno:

Código malicioso del atacante
Tras obtener el contenido de la petición, el JavaScript realizará una petición POST al sitio del atacante incluyendo el contenido de la web interna para almacenarlo en el servidor.
Por otro lado, Access-Control-Allow-Origin también permitiría evadir los
Anti-Forgery Token. Este impedirá que un atacante pudiese forzar una acción en la web, sin que el usuario se diese cuenta.
Gracias a que CORS comparte el contenido de la página, se podría montar la otra web en un contenedor o un IFRAME y obtener el token haciendo una consulta al árbol DOM o filtrando por expresiones regulares:

Código para obtener el token de verificación En este caso imprimimos el token, aunque podría usarse para formar una petición con parámetros y con ello ejecutar una acción:

Muestra del token de verificación
CORS es
una forma de intercambiar información entre dominios, y esta funcionalidad abre otro vector para permitir que CORS pueda ser utilizado como puerta trasera para enviar información fuera de un dominio. Por ejemplo, en el caso de la existencia de un XSS, podría enviar la cookie de sesión para realizar un hijacking. Sería un comportamiento similar a lo que se ha dado en llamar s
hell of the future.
En cualquier caso CORS no es la única manera de intercambiar información entre dominios, pues con HTML 5 aparecen más formas que facilitan esta tarea y así nuevos vectores de ataque.
WebMessage
Otra forma de comunicarse entre dominios es WebMessage
que permite mandar y recibir mensajes mediante JavaScript
sin necesidad de incluir una cabecera. Para usar esta funcionalidad basta con indicarlo en el JavaScript del "servidor" que recibirá el mensaje con un manejador de eventos y en la parte cliente que enviará el mensaje:

Código JavaScript del servidor para recibir para e imprimir el mensaje

Código JavaScript para enviar el mensaje
Es importante tener en cuenta de que en caso de que el "servidor" no maneje los mensajes, estos nunca llegarán.
Al necesitar un manejador explícito para usar
WebMessage
no se implementa SOP directamente, por lo que es importante comprobar
el origen del cliente, porque si el servidor no comprueba el origen en su lógica, podría ser usado (y abusado) por otros dominios.
Además también es importante comprobar el contenido enviado por el usuario porque podría ser un vector de ataque para realizar un XSS a través de
WebMessage:

Ejemplo de XSS preparado con WebMessage
* Intercambio de datos entre páginas: SOP, CORS y WebMessage (I)
Oscar Sánchez
oscar.sanchez@11paths.com