Cuando se abre una página web, cargar datos de se­r­vi­do­res ajenos está, en teoría, es­tri­c­ta­me­n­te prohibido. Sin embargo, puede haber ex­ce­p­cio­nes: si los ad­mi­ni­s­tra­do­res de ambas webs han acordado trabajar juntos, no hay por qué evitar el in­te­r­ca­m­bio. En estos casos, el llamado cross-origin resource sharing (CORS) regula la co­la­bo­ra­ción. Te ex­pli­ca­mos 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 se­r­vi­do­res ajenos al acceder a una página web. Todos los datos deben provenir de la misma fuente, es decir, co­rre­s­po­n­der al mismo servidor. Se trata de una medida de seguridad, ya que Ja­va­S­cri­pt y CSS podrían cargar, sin que el usuario lo supiese, contenido de otros se­r­vi­do­res (y, con este, también contenido malicioso). Tales intentos son de­no­mi­na­dos “cross-origin requests”. Si, por el contrario, ambos ad­mi­ni­s­tra­do­res web saben del in­te­r­ca­m­bio de contenido y lo aprueban, no tiene sentido impedir este proceso. El servidor so­li­ci­ta­do (es decir, aquel del que se quiere cargar contenido) puede permitir entonces el acceso mediante cross-origin resource sharing, en ca­s­te­llano, in­te­r­ca­m­bio de recursos de origen cruzado.

Este permiso se da, no obstante, úni­ca­me­n­te 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 es­pe­cí­fi­ca­me­n­te qué se­r­vi­do­res pueden cargar datos y ponerlos a di­s­po­si­ción del usuario. El acceso ge­ne­ra­li­za­do a todos los clientes se permite úni­ca­me­n­te mediante una “wildcard” o ce­r­ti­fi­ca­do comodín. Esta solución, sin embargo, solo es co­n­ve­nie­n­te para se­r­vi­do­res cuyo contenido debe estar a di­s­po­si­ción del público general, como es el caso, por ejemplo, de las ti­po­gra­fías web.

Si todo sale bien, el usuario no se percatará en absoluto del in­te­r­ca­m­bio entre ambos se­r­vi­do­res. Todos los na­ve­ga­do­res actuales soportan el CORS, y el envío de so­li­ci­tu­des y re­s­pue­s­tas sucede rá­pi­da­me­n­te al solicitar una página web sin que el usuario lo note.

Es­tru­c­tu­ra de la CORS header

De acuerdo con la política de seguridad del mismo origen, en una conexión entre se­r­vi­do­res, los datos re­fe­re­n­tes 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 es­pe­cí­fi­cos no suelen dar problemas. GET y HEAD no pueden alterar datos y, por lo tanto, no suelen co­n­si­de­rar­se 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 ma­li­cio­sas, por lo que en estos casos también hay que activar el cross-origin resource sharing, ya que CORS no solo puede contener in­fo­r­ma­ción sobre el origen permitido, sino también acerca de qué pe­ti­cio­nes HTTP están pe­r­mi­ti­das 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 tra­n­s­mi­tir al servidor a co­n­ti­nua­ción y se pregunta si la solicitud es co­n­si­de­ra­da segura. Para ello, se usa la cabecera OPTIONS (OPTIONS header). Una vez se haya recibido una respuesta positiva, ya se puede realizar la solicitud pro­pia­me­n­te dicha.

Existen di­fe­re­n­tes cabeceras o CORS headers y cada una aborda un aspecto distinto. Ya hemos me­n­cio­na­do dos cabeceras im­po­r­ta­n­tes para ide­n­ti­fi­car orígenes seguros y métodos pe­r­mi­ti­dos, pero hay más:

  • Access-Control-Allow-Origin: ¿qué origen está permitido?
  • Access-Control-Allow-Cre­de­n­tia­ls: ¿también se aceptan so­li­ci­tu­des cuando el modo de cre­de­n­cia­les es incluir (include)?
  • Access-Control-Allow-Headers: ¿qué cabeceras pueden uti­li­zar­se?
  • Access-Control-Allow-Methods: ¿qué métodos de petición HTTP están pe­r­mi­ti­dos?
  • 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?

El primer header es es­pe­cia­l­me­n­te im­po­r­ta­n­te, ya que es­pe­ci­fi­ca desde qué otro host se puede acceder al servidor so­li­ci­ta­do. Además de una dirección concreta, en dicha cabecera también se puede incluir una wildcard en forma de asterisco. De esta manera, el servidor permitirá cross-origin requests de cualquier origen.

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, re­s­po­n­de­rá con los CORS headers co­rre­s­po­n­die­n­tes:

Access-Control-Allow-Origin: http://example.com
Access-Control-Allow-Methods: PUT, POST, DELETE

Si las cabeceras de la respuesta no co­rre­s­po­n­die­ran con las es­pe­ci­fi­ca­cio­nes de la solicitud, o si el servidor so­li­ci­ta­do no re­s­po­n­die­se, la cross-origin request no se podría realizar.

Ventajas e in­co­n­ve­nie­n­tes del CORS

El propósito del CORS es eludir la medida de seguridad es­ta­ble­ci­da como co­n­fi­gu­ra­ción pre­de­te­r­mi­na­da (la política de seguridad del mismo origen). Dicha política es, de hecho, un medio muy eficaz para bloquear co­ne­xio­nes po­te­n­cia­l­me­n­te pe­li­gro­sas. Internet, sin embargo, se basa a menudo pre­ci­sa­me­n­te en este tipo de cross-origin requests, ya que muchas de las co­ne­xio­nes entre hosts sí son deseadas.

Por eso, el CORS ofrece una solución in­te­r­me­dia, pe­r­mi­tie­n­do hacer ex­ce­p­cio­nes a la prohi­bi­ción en aquellas si­tua­cio­nes en que las so­li­ci­tu­des de origen cruzado son ex­pre­sa­me­n­te re­que­ri­das. No obstante, se corre el riesgo de que los ad­mi­ni­s­tra­do­res web se apro­ve­chen de las wildcards por comodidad, haciendo que la pro­te­c­ción de la SOP sea en vano. Por eso, es im­po­r­ta­n­te utilizar el CORS solo en casos es­pe­cia­les y co­n­fi­gu­rar­lo de la manera más re­s­tri­c­ti­va posible.

Ir al menú principal