En pocas palabras, se trata de técnicas para decirle al navegador cuándo puede o no puede hacer una solicitud al servidor. Este es un tema que me costó entender cuando comenzaba a tomar relevancia, porque, claro, es contradictorio: Por mucho empeño que ponga en lograr la configuración perfecta, igual cualquiera puede hacer la solicitud que quiera al backend con cURL, o tan solo abrir Postman. Hasta que entendí que no estamos protegiendo al servidor, sino al usuario.
El usuario promedio no va a ponerse a inspeccionar el código y hacer spoofing con mi servidor. Va a hacer click en links y completar formularios. Entonces, es el navegador quien estará cuidando que esos links y formularios sean legítimos. Yo (app web) solo debo decirle qué criterios seguir.
CORS (Cross-Origin Resource Sharing) es un mecanismo implementado por los navegadores cuya función es evitar que una página web cargada desde un origen (por ejemplo, https://miblog.com) pueda hacer solicitudes a otro origen (https://api.otrodominio.com) sin permiso explícito.
Por “origen” entendemos el trinomio protocolo + dominio + puerto. Los tres deben coincidir para considerarse un mismo origen.
Se trata de un mecanismo de seguridad, pero no en el sentido tradicional. No evita que el servidor reciba solicitudes de otros orígenes, pero permite al navegador decidir si se permite o no que una página pueda leer la respuesta de otra. Si la política CORS no permite esa comunicación, el navegador bloquea la respuesta, aunque el servidor haya contestado sin problema.
La web, por diseño, es muy permisiva. Un sitio puede cargar scripts, imágenes, videos o fuentes desde cualquier lado. Y eso está bien. El problema es cuando aparecen vulnerabilidades como XSS.
XSS (Cross-Site Scripting) es una de las formas más comunes de ataques en aplicaciones web. Se basa en inyectar código JavaScript malicioso dentro de una página confiable. Si el atacante logra que su script se ejecute en el navegador de la víctima, puede robar cookies o tokens y hacer acciones en nombre del usuario.
Imaginemos este escenario:
- Tenés la sesión abierta en tu home banking.
- Visitás (sin darte cuenta, claro) una web maliciosa que ejecuta un script que intenta hacer una acción en el servidor de tu banco.
- Como tu navegador tiene guardadas las cookies de sesión del banco, la solicitud se hace con tus credenciales.
- Esa página maliciosa podría leer la respuesta y mostrarla, robarla, o hacer algo peor.
Gracias a CORS, asumiendo que el servidor del home banking está bien configurado, el navegador bloquea el acceso del sitio web malicioso a la respuesta si el banco. El atacante se queda con las manos vacías.
No nos olvidemos del backend: El servidor recibe igual las solicitudes. Por lo tanto, todas las reglas y buenas prácticas de seguridad aplican como si esto no existiera. Jamás te confíes de validaciones del lado del cliente.
CORS no está solo. Hay varias medidas diseñadas específicamente para proteger al usuario de sí mismo, de los sitios que visita, de los scripts que sin saber acepta ejecutar, y de los errores que, a veces, toca heredar.
- CSRF tokens: Evitan que un sitio externo haga acciones no deseadas en nombre del usuario en sitios donde ya tiene una sesión activa.
- Content Security Policy (CSP): Limita desde dónde se pueden cargar scripts, imágenes o estilos, reduciendo la superficie de ataque para XSS.
- Same site cookies: Evitan que ciertas cookies se envíen en solicitudes cross-site, lo que también ayuda a prevenir CSRF.
Todos estos mecanismos trabajan en conjunto para poner límites a lo que una web puede hacer desde el navegador, y tienen más que ver con la seguridad del usuario que con la protección del servidor en sí. No reemplazan validaciones de autenticación o autorización. Constituyen solo una capa más, complementaria, que evita filtraciones de datos a sitios no confiables cuando el usuario ya está autenticado.
Entender CORS es fundamental para todo desarrollador web, pero más aún es comprender qué problema viene a resolver. La web está pensada para compartir, pero también para cuidar. Y en este equilibrio, mecanismos como CORS, CSP o Same site juegan un rol clave.
Asimismo es fundamental entenderlo cuando nos encontramos con un error de CORS y (creemos que) necesitamos relajar un poco las reglas. Considerá las opciones y las consecuencias, no lo desactives y ya.