¿Has visto lo anterior antes? Probablemente… y probablemente bastante…
Hay millones de artículos que explican cómo solucionar el error anterior, pero ¿qué es exactamente esto de “Intercambio de recursos de origen cruzado” (CORS) y por qué existe?
¿¿¿Por qué???
Comencemos respondiendo primero la pregunta de por qué a través de un escenario y cómo se desarrollaría en diferentes puntos del tiempo.
Imagina esto: inicias sesión en
bank.com, tu servicio bancario. Después de iniciar sesión, se almacena una "cookie de sesión" en tu navegador. (Las cookies de sesión básicamente le indican al servidor
bank.com que tu navegador ha iniciado sesión en tu cuenta). Todas las futuras solicitudes a
bank.com contendrán esta cookie, y puede responder correctamente sabiendo que has iniciado sesión. Bien, ahora decides revisar tu buzón. Ves un correo electrónico sospechoso y, por supuesto, decides hacer clic en el enlace que te envía a
attack.com. A continuación, este sitio web envía una solicitud a
bank.com para obtener tus datos bancarios. Ten en cuenta que
bank.com sigue pensando que has iniciado sesión debido a esa cookie de sesión... esa cookie se almacena en tu navegador. Para los servidores detrás de
bank.com, parece que has solicitado tus datos bancarios normalmente, por lo que los envía de vuelta. Ahora
attack.com tiene acceso a estos y los almacena en otro lugar de forma maliciosa.
La gente se dio cuenta de que esto era perjudicial, así que los navegadores adoptaron una política de origen único (SOP, por sus siglas en inglés) que, si el navegador detecta que se intentan realizar solicitudes a
bank.com desde un lugar distinto a
bank.com y se bloquearán. Es fundamental comprender esto: se trata de una política basada en el navegador.
bank.com no permite determinar el origen de una solicitud, por lo que no ofrece mucha protección contra ataques como CSRF. El navegador que utiliza interviene y, básicamente, indica que, si intenta solicitar información sobre un origen (esquema + nombre de dominio + puerto, https//foo.com:4000, http//bar.org:3000, etc., es decir, la URL), solo enviará las solicitudes al mismo origen.
Esto era genial, pero era increíblemente limitante. Es decir, las API públicas no funcionaban en absoluto. No se podían solicitar datos a menos que se usara algún tipo de proxy.
CSRF
La cuestión es que los servidores pueden identificar de dónde proviene una solicitud. Existe el encabezado "Origen", que las solicitudes deben tener, que muestra el origen de la solicitud. Por ejemplo, en el ejemplo anterior, la solicitud se vería así.
Solicitud a -----> bank.com
{
Encabezados: { Origen: http://attack.com }
}
bank.com en teoría, debería comprobar esto para asegurarse de que solo responda a solicitudes cuyo origen tenga sentido. Y suele ser así, por lo que el procedimiento operativo estándar (SOP) parece algo limitante.
Aquí es donde entra en juego CORS.
CORS
Cuando una aplicación web
example.com intenta solicitar recursos de
bank.com, el navegador incluye automáticamente un
Origin encabezado en la solicitud que indica su origen (example.com). Aquí está la parte crucial: en lugar de bloquear directamente estas solicitudes de origen cruzado según el SOP, el servidor de
bank.com puede inspeccionar este
Origin encabezado y decidir si permite o deniega la solicitud según su propia política CORS.
Si
bank.com considera a
example.com confiable o el recurso solicitado está destinado a ser de acceso público, puede responder con encabezados CORS específicos, como
Access-Control-Allow-Origin, que indican qué orígenes tienen permiso para acceder al recurso. Este encabezado puede configurarse como
http://example.com, permitiendo explícitamente este origen, o
* para recursos públicos a los que cualquier origen puede acceder.
Por supuesto, el navegador facilita todo esto. Si algo falla, recibirás ese molesto error.
Ahora bien… ¿qué pasa si la solicitud no tiene el encabezado
Origin? ¿Qué pasa si tiene muchos otros encabezados y no utiliza ninguno de los métodos HTTP básicos?
En estas situaciones, la gestión de CORS se vuelve un poco más compleja, ya que deja de ser una simple solicitud. Aquí es donde entra en juego el concepto de solicitudes "preflight" en CORS.
Pre-vuelo (Preflight)
Para ciertos tipos de solicitudes que podrían modificar datos en el servidor (aquellas que utilizan métodos HTTP como PUT y DELETE, o que usan encabezados que no se incluyen automáticamente en cada solicitud), los navegadores enviarán primero una solicitud de verificación previa "preflight" antes de realizar la solicitud. Esta solicitud de verificación previa es una solicitud HTTP OPTIONS y su propósito es verificar con el servidor si es seguro enviar la solicitud.
La solicitud de
preflight incluye encabezados que describen el método HTTP y los encabezados de la solicitud real. Esto es lo que sucede a continuación:
- Respuesta del servidor: Si el servidor admite la política CORS y la solicitud, responde a la solicitud de preflight con encabezados que indican qué métodos y encabezados están permitidos. Esto puede incluir encabezados como Access-Control-Allow-Methods y Access-Control-Allow-Headers.
- Decisión del navegador: Según la respuesta del servidor a la solicitud de preflight, el navegador decide si procede con la solicitud. Si la respuesta del servidor indica que la solicitud es permitida, el navegador la envía; de lo contrario, la bloquea y se mostrará un error relacionado con CORS.
Conclusión
Ahora, espero que entiendas un poco más sobre CORS. Creo que lo más importante es entender que todo esto se refiere a la política del navegador, y tu servidor debe estar codificado para cumplirla. Esto está implementado para garantizar tu seguridad. Si usas Chrome, no deberías preocuparte tanto por hacer clic en enlaces incorrectos (por supuesto, aún deberías preocuparte un poco. Sin embargo, esta no es una política infalible. Si usas un navegador de terceros que no cumple con los estándares, todo esto se perderá. ¡Por eso hay que tener cuidado con el software que se usa!
Fuente: traducido al español y tomado de Medium.com en inglés -
https://levelup.gitconnected.com/cors-finally-explained-simply-ae42b52a70a3
Escrito por:
Oleks Gorpynich