Many modern Web applications (and their developers) depend on nearly frictionless and simultaneous access to Web APIs from multiple API providers. But like a firewall that closes off access to untrusted parties in the name of security, the Web's default is to prevent such "loose" behavior. Thankfully, that default can be securely overridden. However, it is incumbent on both the developers of Web applications and the API providers that service them to understand the principles of what is known as Cross-Origin Resource Sharing (CORS) before doing so.
CORS is a security mechanism that allows a Web page from one domain (aka an Origin) to access a resource from a different origin (what's known as a cross-domain request). Modern browsers normally reject such requests because they default to a "same-origin policy." CORS, therefore, is essentially a relaxation of that same-origin policy and without it, websites are restricted to accessing resources from the same origin.
The same-origin policy exists to prevent malicious behavior. Without same-origin policy, an attacker could do things like hijack authentication cookies to perform malicious behavior, such as withdrawing money from your bank account when you're signed into online banking. Let's walk through an example.
About the Same-origin Policy
This means when you log into https://examplebank.com, a cookie is stored in your browser for https://examplebank.com. If that bank is a React single-page app (SPA), they may have created a REST API at https://examplebank.com/api for the SPA to communicate via AJAX.
The CSRF Vulnerability Without a Same-origin Policy
Let's say you browse to the malicious website https://evilunicorns.com while logged into https://examplebank.com. Without the same-origin policy that hacker website could make authenticated malicious AJAX calls to the API's "withdraw funds" resource (i.e., POST /withdraw) at https://examplebank.com/api even though the hacker's 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. This type of attack is called Cross-Site Request Forgery (CSRF).
How Same-origin Prevents This Attack
By restricting HTTP calls to only ones to the same origin (i.e., the domain indicated in the URL field of the browser), the same-origin policy closes some of these hacker backdoors, such as this Cross-Site Request Forgery (CSRF) attack as the browser would not allow the https://evilunicorns.com to make AJAX calls to https://examplebank.com as these are two different origins.
How is Origin Defined?
So, what constitutes a unique origin? Origin refers to the content who initiated the request, which is usually the open browser tab, but it could also be the origin of an iFrame window. Origin includes a combination of protocol (e.g., http, ftp, etc.), domain, and port. This means that https://api.mydomain.com and https://mydomain.com are actually different origins and thus impacted by same-origin policy. In a similar way, http://localhost:9000 and http://localhost:8080 are also different origins. The path as well as any query parameters are ignored when considering the origin.
Why CORS Was Created
There are legitimate reasons for a website to make cross-origin HTTP requests. Maybe a single-page app at https://mydomain.com needs to make AJAX calls to https://api.mydomain.com or maybe https://mydomain.com incorporates some third-party fonts or analytics providers like Google Analytics or MixPanel. CORS securely enables these cross-domain requests.