4º. 1er cuatrimestre. Itinerario de Sistemas de la Información. Grado en Ingeniería Informática. ULL
The default behavior of web browsers that initiate requests from a page via JavaScript is that they follow the same-origin policy.
Two URLs would be considered to be having different origins when they have different protocols, ports (if specified), or hosts.
Origin includes the combination of protocol, domain, and port. This means
are actually different origins and thus impacted by same-origin policy.
In a similar way,
are also different origins. The path or query parameters are ignored when considering the origin.
Under SOP requests can only be made to the same domain. Requests to a different domain will fail.
Websites use cookies to keep track of authentication or session info. Those cookies are bounded to a certain domain when they are created.
On every HTTP call to that domain, the browser will attach the cookies that were created for that domain. This is on every HTTP call, which could be for static images, HTML pages, or even AJAX calls.
This means when you log into https://examplebank.com, a cookie is stored for https://examplebank.com. If that bank is a single-page React app, they may have created a REST API at https://examplebank.com/api for the SPA to communicate via AJAX.
POST /withdraw
even though the hacker website doesn’t have direct access to the bank’s cookies.This is due to the browser behavior of automatically attaching any cookies bounded to https://examplebank.com for any HTTP calls to that domain, including AJAX calls from https://evilunicorns.com to https://examplebank.com.
By restricting HTTP calls to only ones to the same origin (i.e. the browser tab’s domain), same-origin policy closes some hacker backdoors such as around Cross-Site Request Forgery (CSRF) and Cross-Site Scripting (XSS).
So, all browsers simply restrict script-based network calls to their own domain to make it simple and safe.
CORS allows these cross-domain requests to happen, but only when each side opts into CORS support.
If your server is configured for CORS, it will return an extra header with Access-Control-Allow-Origin
on each response.
Sometimes it’s just a helpful website (say, https://my.first.site.foo) trying to use a public API from another origin (say, https://api.github.com). The programmers who worked hard on api.github.com want all origins to access their site’s contents freely. In that case, the API server at api.github.com can use CORS headers to allow my.first.site.foo (or any other requesting origin) to access its API responses.
So, most of the time cross-origin access is a bad thing, but there are cases where it’s a good thing. CORS allows the good case to happen when the requested site wants it to happen.
CORS allows the server to explicitly whitelist certain origin and help to bypass the same-origin policy.
This is how a simple CORS request works:
https://www.mydomain.com
initiates AJAX request GET https://api.mydomain.com/widgets
Host
, the browser automatically adds the Origin
Request Header for cross-origin requests: GET /widgets/ HTTP/1.1
Host: api.mydomain.com
Origin: https://www.mydomain.com
[Rest of request...]
Origin
request header. If the Origin value is allowed, it sets the Access-Control-Allow-Origin
to the value in the request header Origin
. HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://www.mydomain.com
Content-Type: application/json
[Rest of response...]
Access-Control-Allow-Origin
header to see if it matches the origin of the tab. If not, the response is blocked.Access-Control-Allow-Origin
matches the single origin exactly or contains the wildcard *
operator.Access-Control-Allow-Origin: *
allows all origins.
Use *
if your application absolutely requires it, such as creating an open/public API.If you want to know more about CORS continue reading the section Cross-Origin Resource Sharing CORS: Second Part of the course.
If you want to avoid the blocking, the server that hosts the resource needs to have CORS enabled.
What you can do on the client side is set the mode of fetch
to cors
(Not really needed, this is the default setting):
fetch(request, {mode: 'cors'});
The mode
option specifies the mode you want to use for the request, e.g., cors
, no-cors
, or same-origin
.
same-origin
you can perform requests only to your origin
, otherwise the request will result in an error.no-cors
, you can perform requests to other origins, even if they don’t set the required CORS headers, but you’ll get an opaque response. With an opaque response we won’t be able to read the data returned or view the status of the request, meaning we can’t check if the request was successful or not.However this still requires the server to enable CORS as well, and allow your domain to request the resource.