Same-Origin Policy(SOP) and Cross-Origin Resource Sharing(CORS) Mechanism are all Web Browser based. That means It is Browser to implement them.
What is SOP
The Same-Origin Policy(SOP) is a browser security feature that restricts HOW documents and scripts on one origin can interact with resources on another origin.
It restricts scripts on a web page from freely making cross-origin requests. It is default behavior of browsers. It stops malicious websites from accessing other websites, protecting against attacks such as cross-site scripting (XSS), cross-site request forgery (CSRF), and session/cookie theft etc.
A ‘cross-origin request’ is a web request (either fetch or XMLHttpRequest) that is initiated from a script on one domain (e.g., mysite.com) to another domain (e.g., othersite.com). Browsers will detect whether a request is cross-origin or same-origin request.
By default, SOP blocks cross-origin HTTP requests initiated by scripts. There are several use cases that require cross-origin script access; for example, Content Delivery Networks (CDNs) that provide hosting for JavaScript/CSS libraries and public API endpoints.
Browsers are using CORS to handle cross-origin script access.
What is CORS
Cross-Origin Resource Sharing (CORS) is an HTTP-header based mechanism that allows a server to indicate any origins (domain, scheme, or port) other than its own from which a browser should permit loading resources. CORS also relies on a mechanism by which browsers make a “preflight” request to the server hosting the cross-origin resource, in order to check that the server will permit the actual request. In that preflight, the browser sends headers that indicate the HTTP method and headers that will be used in the actual request.
CORS is Web Browser based mechanism
To understans CORS, you need to clear three parties:
- Browser
- Domain A
- Domain B
CORS defines a way for client web applications or script that are loaded in domain A to interact with resources in Domain B.
Basic logic on How CORS work
A cross-origin request example: the front-end JavaScript code served from ‘https://domain-a.com’ uses fetch()
to make a request for ‘https://domain-b.com/data.json’.
Browsers will restrict this request! The APIs fetch()
and XMLHttpRequest
follow the same-origin policy. This means that a web application using those APIs can only request resources from the same origin the application was loaded from unless the response from other origins includes the right CORS headers.
Main points
- It is Domain B who implement CORS policy to specify/declare which origins are allowed to make cross-origin requests to it’s resource. For example set up The HTTP response headers
Access-Control-Allow-Origin
to define the non-same origins that are allowed to make requests to pages on your domain. - The cross-origin request from Domain A won’t be fulfilled unless the Domain B origin allows for the request.
- CORS is based on HTTP headers.
- CORS is Web Browser based mechanism.
- The CORS mechanism supports secure cross-origin requests and data transfers between browsers and servers. Browsers use CORS in APIs such as
fetch()
orXMLHttpRequest
to mitigate the risks of cross-origin HTTP requests. - Developers making cross-origin requests do not have to set any cross-origin sharing request headers programmatically. Browsers do that for you.
CORS three scenarios
Here are three scenarios that demonstrate how Cross-Origin Resource Sharing works.
Simple requests
A simple request is one that meets some conditions, like: using GET or HEAD or POST methods; etc. A simple requests don’t trigger a CORS preflight.
Make request like below, Browser will set up the header for you:
const fetchPromise = fetch("https://bar.other");
fetchPromise
.then((response) => response.json())
.then((data) => {
console.log(data);
});
In response, the server returns a Access-Control-Allow-Origin
header with Access-Control-Allow-Origin: *
, which means that the resource can be accessed by any origin.
Preflighted requests
Unlike simple requests, for “preflighted” requests the browser first sends an HTTP request using the OPTIONS
method to the resource on the other origin, in order to determine if the actual request is safe to send. Such cross-origin requests are preflighted since they may have implications for user data.
Make request:
const fetchPromise = fetch("https://bar.other/doc", {
method: "POST",
mode: "cors",
headers: {
"Content-Type": "text/xml",
"X-PINGOTHER": "pingpong",
},
body: "<person><name>Arun</name></person>",
});
fetchPromise.then((response) => {
console.log(response.status);
});
Browser send preflight request with the OPTIONS method for you. along with the OPTIONS request, two other request headers are sent:
Access-Control-Request-Method: POST
Access-Control-Request-Headers: content-type,x-pingother
Domain B need to response, like Access-Control-Allow-Origin: https://foo.example
to go ahead. And then the real Request is coming.
Requests with credentials
To ask for a fetch() request to include credentials, set the credentials option to “include”.
const url = "https://bar.other/resources/credentialed-content/";
const request = new Request(url, { credentials: "include" });
const fetchPromise = fetch(request);
fetchPromise.then((response) => console.log(response));