﻿# Cross\-Origin Resource Sharing \(CORS\)

Cross\-Origin Resource Sharing \(CORS\) is a mechanism that enables web pages to request resources from a server hosted on another origin, where an origin is defined as a web server that differs in domain, port, or protocol from the one making the request\.

By default, modern browsers restrict web pages from accessing resources if a request is sent to the server via a different port, domain, or protocol than that of the page\. This security mechanism is called the **Same\-Origin Policy \(SOP\)**\. The intent behind this policy is to prevent unauthorized access to various website resources\.

However, in today's web technology landscape, it's quite common for web pages to send requests to servers hosted on different domains\. To regulate it properly, CORS has been introduced\. It controls both access to responses from an external source and whether the request can be sent at all\. 

Browsers regulate the process by reading server response headers\. If the server does not send the required values in special CORS headers, browsers will either restrict the page's access to the server's response or blocks the request from being sent\. 

Here are the main CORS headers:

* `Access-Control-Allow-Origin` specifies which origins have permission to receive server's response as part of cross\-domain requests\. If the server response does not contain the `Access-Control-Allow-Origin` header with the origin value that has initiated the cross\-domain request, either the main request will be blocked or the responses won't be provided to the page\.
* `Access-Control-Allow-Credentials` determines whether `credentials` \(for example, cookies\) are allowed within cross\-domain requests\. If user cookies are passed in the request, and the `Access-Control-Allow-Credentials` value is `false`, either the main request will be blocked or the page won't receive the response\.
* `Access-Control-Allow-Methods` defines which methods are allowed within cross\-domain requests\. If the response to the preflight request does not include the main request method in this header, it's blocked from being sent\.
* `Access-Control-Allow-Headers` defines which headers are allowed within cross\-domain requests\. If the main request contains a header that is not specified in `Access-Control-Allow-Headers`, it's blocked from being sent\.

In CORS, there are two types of requests: simple and preflight\. The request type determines which headers within the server response are required, whether the request will be blocked, or the web page won't receive the server response\.

The following are simple scenarios for implementing both types of requests\.

## Simple requests

We consider a request as simple if:

* the `GET`, `HEAD`, or `POST` method is used;
* there are CORS\-safelisted request\-headers: `Accept`, `Accept-Language`, `Content-Language`, `Content-Type`, or `Range`;
* the `Content-Type` header contains one of the following values: `application/x-www-form-urlencoded`, `multipart/form-data`, or `text/plain`\.

Let's imagine that we need to send the `GET` request containing the `Content-Type` header with the `text/plain` value\. The request will be sent from the `http://localhost:4000` page to the server located at `http://localhost:4001`\. 

The request will be sent, and a respond with a valid status code will be received\. However, since the ports of the web page and the server differ, the **Same\-Origin Policy** won't be fulfilled, and the browser will restrict the page access to the response\.

For the page to access the response, the server must return a valid `Access-Control-Allow-Origin` CORS header with `http://localhost:4000`\. In this case, the browser grants the page access to the response content\.

If the request includes any `credentials` \(like cookies or TLS certificates\), and the server response doesn't contain the `Access-Control-Allow-Credentials` header with the `true` value, the browser will restrict the page access to the response\.

## Preflight requests

If requests don't meet the criteria for a simple request, the browser will send a preflight request before sending the simple one to the server\. 

For example, if we replace the `GET` method with `DELETE` in the request, the browser will process it differently: the preflight request with the `OPTIONS` method will be sent to the server before the main one\. It will contain information about the main request, including its method, the address of the web page from which it was sent, and its headers\.

The browser expects to receive the necessary CORS headers in response\. However, there's an important difference: if the response to the preflight request does not fulfill the browser, the main request won't be sent\. 

As in the previous example, we expect to see the `Access-Control-Allow-Origin` header with `http://localhost:4000` in the response to the preflight request\. 

Other CORS headers play an important role as well\. For example, if the `Access-Control-Allow-Methods` header does not contain `DELETE`, the main request won't be sent either\.

## The principle of least privilege

There is one important detail to highlight when working with CORS\. In addition to a specific host, the `Access-Control-Allow-Origin` header can take the `*` \(wildcard\) value\. It authorizes any host to view the contents of the server response\. This can be non\-compliant behavior, especially if these resources are expected for web pages with a specific domain\.

The same applies to the `Access-Control-Allow-Credentials` header with the `true` value\. Use it carefully, especially if the value of the `Access-Control-Allow-Origin` header is dynamically generated on the server rather than taken from a predefined whitelist\. This can lead to significant security vulnerabilities\.

Violating the principle of least privilege can expose web applications to security risks:

* Credentials may leak when transitioning from a corporate network to the public internet\.
* Attackers may manipulate your application API as their own\.
* If the website is vulnerable to XSS, the consequences of an attack may be more severe\.

So, if the application is not deployed in a test environment or is not intended to serve as a public API, the `Access-Control-Allow-Origin` header should be defined with a specific whitelisted value\.

If you wish to learn more about the possible vulnerabilities that misconfigured CORS can lead to, the articles below offer helpful insights:

* [OWASP\. Testing Cross Origin Resource Sharing](https://owasp.org/www-project-web-security-testing-guide/latest/4-Web_Application_Security_Testing/11-Client-side_Testing/07-Testing_Cross_Origin_Resource_Sharing)
* [PortSwigger\. Vulnerabilities arising from CORS configuration issues](https://portswigger.net/web-security/cors#vulnerabilities-arising-from-cors-configuration-issues)
* [PortSwigger\. Exploiting CORS misconfigurations for Bitcoins and bounties](https://portswigger.net/research/exploiting-cors-misconfigurations-for-bitcoins-and-bounties)

To delve deeper into the CORS theory, welcome to the following pages:

* [Mozilla\. Cross\-Origin Resource Sharing \(CORS\)](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CORS)
* [Mozilla\. Same\-origin policy](https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy)
* [OWASP Cheat Sheet Series\. HTML5 Security Cheat Sheet\. Cross Origin Resource Sharing](https://cheatsheetseries.owasp.org/cheatsheets/HTML5_Security_Cheat_Sheet.html#cross-origin-resource-sharing)