Same-Origin Policy

Francisco Canteli
8 min readMay 17, 2021

--

Web Security Fundamentals

Introducción

Este post tiene como objetivo explicar que es la Same-Origin Policy, como funciona y porque es tan importante saber de ella a la hora de auditar un sitio web.

¿Que es un origen?

Para entender que es un origen, primero tenemos que ver una URL tradicional, en donde podremos destacar las siguientes partes:

  • Scheme: El protocolo que utiliza (HTTP o HTTPS)
  • Domain: Dominio al que pertenece la URL
  • Port: El puerto (El cual normalmente es 80 o 443)
Partes de una URL

El origen es determinado por estas tres partes. Debido a esto, cuando miramos dos URL podremos determinar si tienen el mismo origen en caso de que el Scheme, Domain y Port sean iguales.

Ejemplo de URLs con el mismo origen

Same-Origin Policy (SOP)

Fundamentalmente, la Same-Origin Policy restringe cómo un documento o un script cargado desde un origen evil.com puede interactuar con un recurso de otro origen bank.com. Ahora bien, porque esto es importante? Debido a que de no existir esta política, un sitio web podría acceder a datos de otros sitios webs ya que nos permite aislar los sitios uno del otro. El objetivo principal de la Same-Origin Policy es mantener la información sensible segura evitando lecturas no autorizadas.

Veamos su funcionamiento más detenidamente…

Cuando nosotros abrimos una página sitioA.com en un navegador, en la pestaña se crea un nuevo “contexto” en el cual se encuentra el DOM del sitio y dentro de este contexto se correran los scripts del sitio sitioA.com. Cada ventana o pestaña, se encuentra aislada de las otras debido a que cada una se encuentra en su propio “contexto”, pero si ambas pestañas o ventanas cuentan con el mismo origen, podrán acceder a sus datos entre sí.

Diferentes sitios abiertos contenidos en distintos contextos

Al abrir una nueva pestaña sitioB.com, esta vuelve a crear un nuevo “contexto” separado del sitio anterior. Siguiendo el ejemplo, puede el Sitio A acceder al DOM del Sitio B?

Diagrama del escenario planteado

La respuesta es NO! El sitio no va a poder acceder debido a la SOP, pero quien permite o deniega que el sitioA.com pueda acceder al DOM del sitioB.com? El encargado de permitir o denegar el acceso es el navegador. El navegador debe implementar la SOP para proteger que un sitio (Por ej. Un sitio malicioso) acceda a los datos del otro sitio. Un dato muy importante es que si bien el encagado es el navegador, el servidor web puede influir sobre esta protección.

Reglas de SOP

La Same-Orgin Policy controla las interacciones entre dos orígenes diferentes (Cross-origin), como cuando se usa XMLHttpRequest o un elemento <img>. Estas interacciones habitualmente se ubican en tres categorías:

  • Las escrituras Cross-origin normalmente se permiten. Como ejemplo tenemos los enlaces, redirecciones y envíos de formulario.
  • La integración Cross-origin (embedding) normalmente se permite.
  • Las lecturas Cross-origin habitualmente no se permiten, pero el acceso de lectura es a menudo filtrado mediante integración.

Aplicación de la SOP en distintos escenarios

Como ya vimos anteriormente, la SOP nos restringe cómo un documento o un script cargado desde un origen puede interactuar con un recurso de otro origen. Hasta ahora solo vimos un escenario posible en el cual un sitio sitioA.com intenta acceder a los recursos de otro sitio sitioB.com dentro del navegador.

Ahora, agregaremos otro escenario más, en el cual un sitio sitioA.com realiza una solicitud otro sitio sitioB.com para acceder a sus recursos. Siguiendo el ejemplo, sitioA.com podrá realizar la solicitud a sitioB.com pero no podrá obtener la respuesta.

Ambos escenarios planteados

Interacción Cross-Origin escritura

Las interacciones Cross-Origin de escritura más comúnes son la utilización de enlaces, las redirecciones y los envíos de formularios. En este caso, veremos un ejemplo de como funciona una interacción Cross-Origin con envíos de formularios por POST y en los links.

Ejemplo de SOP en Forms

Los formularios pueden hacer una solicitud POST a otros sitios, al enviarse, la respuesta cargará en un nuevo contexto (Debido a esto, el sitio original será remplazado con el sitio accedido). Por lo cual nuevamente un formulario podrá realizar una solicitud POST a cualquier sitio, pero no puede leer la respuesta.

Código de ejemplo

<form action="http://siteb.com/" method="POST">

Diagrama

Escenario con Forms

Sin embargo, que previene que un sitio malicioso pueda enviar los datos de un formulario a otro sitio y este sitio realice determinada acción (Por Ej. Que un sitio evil.com tenga un formulario que al enviarse se envíe a bank.com y realice una transferencia)? En este caso, estaríamos frente a una vulnerabilidad Cross-Site Request Forgery (CSRF) y la manera de prevenir que esto ocurra sería utilizando tokens Anti-CSRF.

En resumen, SOP evita que el sitio evil.com pueda obtener la respuesta de bank.com pero no que se realice la solicitud que permite que se haga la transferencia, para evitar eso debemos usar tokens Anti-CSRF.

Ejemplo de SOP en XMLHttpRequest

Al igual que con los formularios, podremos hacer solicitudes a otros sitios pero no podremos leer la respuesta.

Código de ejemplo

<script>
var req = new XMLHttpRequest();
req.open(“GET”, “https://sitioa.com", false);
req.send();
</script>

Diagrama

Escenario con XMLHTTPRequest

Ejemplo de SOP en anchors

Los sitios pueden crear un links a otros sitios, al hacer click accederemos al otro sitio el cual será cargado en nuestro navegador en un nuevo contexto (Debido a esto, el sitio original será remplazado con el sitio accedido). Cualquier sitio puede crear un link, pero no puede leer la respuesta.

Código de ejemplo

<a href="http://siteb.com/>

Diagrama

Escenario con Anchors

Interacción Cross-Origin integración (Embedding)

Las interacciones Cross-Origin de integración más comunes son la integración de Scripts, archivos CSS, imágenes y otros archivos multimedia. A continuación, veremos ejemplos de como funciona una integración Cross-Origin.

Ejemplo de SOP en Frames o IFrames

Si nosotros embebemos un sitio sitioa.com en nuestro sitio sitioprincipal.com podremos leer los datos del contexto de este sitio sitioa.com? La respuesta es no! No podremos acceder a este sitio, a no ser que se enbeba un sitio con el mismo origen.

Diagrama

Escenario con Frames y IFrames

Es importante aclarar, que también podemos evitar el cross-origin embedding (Es decir, que el sitioa.com se pueda embeber en sitioprincipal.com) si utilizamos el header X-Frame-Options.

Ejemplo de SOP en Imágenes y Archivos Multimedia

Cualquier sitio puede mostrar imágenes de cualquier otro sitio, sin embargo, los sitios no pueden leer datos de la imagen de otros sitios. Esto aplica también a otros archivos multimedia como videos y audios.

Código de ejemplo

<img src="http://siteb.com/pic.jpg" />

Diagrama

Escenario con Imágenes

Ejemplo de SOP en Archivos CSS

Cualquier sitio puede incluir CSS de cualquier otro sitio, sin embargo, los sitios no pueden leer datos del CSS de otros sitios.

Código de ejemplo

<link rel="stylesheet" type="text/css" href="http://siteb.com/site.css" /> 

Diagrama

Escenario con CSS

Ejemplo de SOP en Archivos JS

Cualquier sitio puede incluir un archivo Javascript de cualquier otro sitio, sin embargo, Javascript corre en su sitio original.

Código de ejemplo

<script src="http://siteb.com/ga.js" />

Diagrama

Escenario con JS

SOP y WebStorage

¿Como se aplica la SOP al Web Storage?

El acceso a datos almacenados en el navegador tales como el localStorage y el sessionStorage son separados por origen. Cada origen obtiene su propio almacenamiento separado, y JavaScript en un origen no puede leer desde o escribir al almacenamiento perteneciente a otro origen.

El localStorage comparte su contenido entre ventanas o pestañas con el mismo origen y su contenido sigue persistiendo en caso de que la ventana o pestaña se cierre.

El sessionStorage no se comparte su contenido entre ventanas y pestañas y es eliminado al cerrar la ventana o pestaña.

Escenario con Web Storage

CORS

Luego de entender que es y como funciona la Same-Origin Policy, podemos empezar a hablar de CORS (Cross-Origin Resourse Sharing). CORS es un mecanismo que utiliza cabeceras HTTP adicionales para permitir que se pueda acceder a recursos seleccionados desde un servidor, en un origen distinto al que pertenece.

Ejemplo sin CORS

Explicado de otra manera, sin CORS ocurriría lo siguiente:

SOP en acción

En resumen, CORS nos permite flexibilizar la SOP y permitir que ciertos dominios. En el siguiente diagrama podemos ver como se utiliza CORS para que el Sitio A, pueda leer la respuesta del Sitio B.

Ejemplo con CORS flexibilizando la SOP

Veamos a continuación como se representaría este escenario en donde se aplicaría CORS:

El Sitio A ejecutaría el siguiente código para realizar la solicitud al Sitio B:

<script>
var req = new XMLHttpRequest();
req. open(“GET”, “https://sitiob.com", false);
req.send();
</script>

Normalmente, el Sitio A no podría leer la respuesta, pero debido a que el Sitio B implementa CORS, el Sitio A podrá leer la respuesta. A continuación, se muestra el header que devuelve el Sitio B indicando que el Sitio A puede leer la respuesta.

Access-Control-Allow-Origin: https://sitioa.com

Es importante aclarar que, si bien no trataremos lo trataremos con profundidad en este post, CORS cuenta con muchas mas funcionalidades que nos permiten determinar, por ejemplo, si la solicitud puede ser envíada con credenciales.

Conclusiones

Como conclusión final podemos determinar que es fundamental conocer la SOP y CORS a la hora de realizar un Web Pentest, dado que en caso de que CORS se encuentre mal configurado, pueden existir distintas vulnerabilidades en el sistema.

También es muy importante entender que la Same-Origin Policy no evita ataques del tipo Cross-Site Request Forgery y que estos deben ser evitados utilizando tokens Anti-CSRF.

Referencias

Referencia Principal

Otras Referencias

https://developer.mozilla.org/es/docs/Web/Security/Same-origin_policy
https://developer.mozilla.org/es/docs/Web/HTTP/CORS
https://securing-the-stack.teachable.com/courses/same-origin-policy/lectures/4970772
https://www.ionos.es/digitalguide/paginas-web/desarrollo-web/cross-origin-resource-sharing/
https://www.youtube.com/watch?v=KaEj_qZgiKY
https://www.youtube.com/watch?v=i0wxon609f8

--

--