CORS: qué es y cómo funciona el cross-origin resource sharing
Cuando se abre una página web, cargar datos de servidores ajenos está, en teoría, estrictamente prohibido. Sin embargo, puede haber excepciones: si los administradores de ambas webs han acordado trabajar juntos, no hay por qué evitar el intercambio. En estos casos, el llamado cross-origin resource sharing (CORS) regula la colaboración. Te explicamos cómo funciona.
¿Cómo funciona el CORS?
La same-origin policy (SOP o política de seguridad del mismo origen) prohíbe que se carguen datos de servidores ajenos al acceder a una página web. Todos los datos deben provenir de la misma fuente, es decir, corresponder al mismo servidor. Se trata de una medida de seguridad, ya que JavaScript y CSS podrían cargar, sin que el usuario lo supiese, contenido de otros servidores (y, con este, también contenido malicioso). Tales intentos son denominados “cross-origin requests”. Si, por el contrario, ambos administradores web saben del intercambio de contenido y lo aprueban, no tiene sentido impedir este proceso. El servidor solicitado (es decir, aquel del que se quiere cargar contenido) puede permitir entonces el acceso mediante cross-origin resource sharing, en castellano, intercambio de recursos de origen cruzado.
Este permiso se da, no obstante, únicamente a clientes concretos, es decir, el CORS no es un comodín para realizar cualquier cross-origin request. En lugar de eso, el segundo servidor permite al primero un acceso exclusivo mediante una cabecera HTTP. En dicha cabecera de la respuesta HTTP está indicado específicamente qué servidores pueden cargar datos y ponerlos a disposición del usuario. El acceso generalizado a todos los clientes se permite únicamente mediante una “wildcard” o certificado comodín. Esta solución, sin embargo, solo es conveniente para servidores cuyo contenido debe estar a disposición del público general, como es el caso, por ejemplo, de las tipografías web.
Si todo sale bien, el usuario no se percatará en absoluto del intercambio entre ambos servidores. Todos los navegadores actuales soportan el CORS, y el envío de solicitudes y respuestas sucede rápidamente al solicitar una página web sin que el usuario lo note.
Este permiso se da, no obstante, únicamente a clientes concretos, es decir, el CORS no es un comodín para realizar cualquier cross-origin request. En lugar de eso, el segundo servidor permite al primero un acceso exclusivo mediante una cabecera HTTP. En dicha cabecera de la respuesta HTTP está indicado específicamente qué servidores pueden cargar datos y ponerlos a disposición del usuario. El acceso generalizado a todos los clientes se permite únicamente mediante una “wildcard” o certificado comodín. Esta solución, sin embargo, solo es conveniente para servidores cuyo contenido debe estar a disposición del público general, como es el caso, por ejemplo, de las tipografías web.
Si todo sale bien, el usuario no se percatará en absoluto del intercambio entre ambos servidores. Todos los navegadores actuales soportan el CORS, y el envío de solicitudes y respuestas sucede rápidamente al solicitar una página web sin que el usuario lo note.
Estructura de la CORS header
De acuerdo con la política de seguridad del mismo origen, en una conexión entre servidores, los datos referentes al origen se componen de tres elementos: host, puerto y protocolo. De este modo, y tomando el ejemplo de la imagen, la directriz prohíbe que ’https://example.com’ acceda a ’http://example.com’ o a ’https://example.org’. En el primer caso, el protocolo no es el mismo y, en el segundo, los datos de host no coinciden.
Una petición de origen cruzado es, en teoría, una petición HTTP. Los métodos específicos no suelen dar problemas. GET y HEAD no pueden alterar datos y, por lo tanto, no suelen considerarse como un riesgo para la seguridad. No se puede decir lo mismo de PATCH, PUT o DELETE: con ellos sí se puede llevar a cabo acciones maliciosas, por lo que en estos casos también hay que activar el cross-origin resource sharing, ya que CORS no solo puede contener información sobre el origen permitido, sino también acerca de qué peticiones HTTP están permitidas por la fuente.
Si se trata de métodos HTTP de seguridad, el cliente envía en primer lugar una solicitud preflight (preflight request) en la que solo se indica qué método HTTP se piensa transmitir al servidor a continuación y se pregunta si la solicitud es considerada segura. Para ello, se usa la cabecera OPTIONS (OPTIONS header). Una vez se haya recibido una respuesta positiva, ya se puede realizar la solicitud propiamente dicha.
Existen diferentes cabeceras o CORS headers y cada una aborda un aspecto distinto. Ya hemos mencionado dos cabeceras importantes para identificar orígenes seguros y métodos permitidos, pero hay más:
Una petición de origen cruzado es, en teoría, una petición HTTP. Los métodos específicos no suelen dar problemas. GET y HEAD no pueden alterar datos y, por lo tanto, no suelen considerarse como un riesgo para la seguridad. No se puede decir lo mismo de PATCH, PUT o DELETE: con ellos sí se puede llevar a cabo acciones maliciosas, por lo que en estos casos también hay que activar el cross-origin resource sharing, ya que CORS no solo puede contener información sobre el origen permitido, sino también acerca de qué peticiones HTTP están permitidas por la fuente.
Si se trata de métodos HTTP de seguridad, el cliente envía en primer lugar una solicitud preflight (preflight request) en la que solo se indica qué método HTTP se piensa transmitir al servidor a continuación y se pregunta si la solicitud es considerada segura. Para ello, se usa la cabecera OPTIONS (OPTIONS header). Una vez se haya recibido una respuesta positiva, ya se puede realizar la solicitud propiamente dicha.
Existen diferentes cabeceras o CORS headers y cada una aborda un aspecto distinto. Ya hemos mencionado dos cabeceras importantes para identificar orígenes seguros y métodos permitidos, pero hay más:
- Access-Control-Allow-Origin: ¿qué origen está permitido?
- Access-Control-Allow-Credentials: ¿también se aceptan solicitudes cuando el modo de credenciales es incluir (include)?
- Access-Control-Allow-Headers: ¿qué cabeceras pueden utilizarse?
- Access-Control-Allow-Methods: ¿qué métodos de petición HTTP están permitidos?
- Access-Control-Expose-Headers: ¿qué cabeceras pueden mostrarse?
- Access-Control-Max-Age: ¿cuándo pierde su validez la solicitud preflight?
- Access-Control-Request-Headers: ¿qué header HTTP se indica en la solicitud preflight?
- Access-Control-Request-Method: ¿qué método de petición HTTP se indica en la solicitud preflight?
- Origin: ¿de qué origen proviene la solicitud?
Ejemplo de cross-origin resource sharing
En el siguiente ejemplo, suponemos que el host A (example.com) quiere enviar una petición DELETE (DELETE request) al host B (example.org). Para ello, el servidor A envía, en primer lugar, una preflight request:
/OPTIONS
Origin: http://example.com
Access-Control-Request-Method: DELETE
Si el host B no se opone a esta cross-origin request, responderá con los CORS headers correspondientes:
Access-Control-Allow-Origin: http://example.com
Access-Control-Allow-Methods: PUT, POST, DELETE
Si las cabeceras de la respuesta no correspondieran con las especificaciones de la solicitud, o si el servidor solicitado no respondiese, la cross-origin request no se podría realizar.
Ventajas e inconvenientes del CORS
El propósito del CORS es eludir la medida de seguridad establecida como configuración predeterminada (la política de seguridad del mismo origen). Dicha política es, de hecho, un medio muy eficaz para bloquear conexiones potencialmente peligrosas. Internet, sin embargo, se basa a menudo precisamente en este tipo de cross-origin requests, ya que muchas de las conexiones entre hosts sí son deseadas.
Por eso, el CORS ofrece una solución intermedia, permitiendo hacer excepciones a la prohibición en aquellas situaciones en que las solicitudes de origen cruzado son expresamente requeridas. No obstante, se corre el riesgo de que los administradores web se aprovechen de las wildcards por comodidad, haciendo que la protección de la SOP sea en vano. Por eso, es importante utilizar el CORS solo en casos especiales y configurarlo de la manera más restrictiva posible.
Por eso, el CORS ofrece una solución intermedia, permitiendo hacer excepciones a la prohibición en aquellas situaciones en que las solicitudes de origen cruzado son expresamente requeridas. No obstante, se corre el riesgo de que los administradores web se aprovechen de las wildcards por comodidad, haciendo que la protección de la SOP sea en vano. Por eso, es importante utilizar el CORS solo en casos especiales y configurarlo de la manera más restrictiva posible.