DEV Community

Cover image for Understanding How CORS Works in Web Browsers
kumarshivam1998
kumarshivam1998

Posted on

Understanding How CORS Works in Web Browsers

Cross-Origin Resource Sharing (CORS) is a critical security feature in web browsers that governs how web applications can request resources (such as data, images, or scripts) from a different domain than the one that served the initial web page. It is primarily designed to protect users from malicious sites attempting to access sensitive information on other websites. This blog will explain how CORS works and why it is crucial for web development.
What is CORS?
In simple terms, CORS is a browser mechanism that controls which resources a web page can request from different domains. By default, browsers implement the Same-Origin Policy (SOP), which restricts web pages from making requests to a domain other than the one from which the page was loaded. This policy is a fundamental security feature that prevents potentially harmful interactions between websites.

However, there are many cases where legitimate cross-origin requests are necessary—for example, when a web application needs to fetch data from an API hosted on a different server. CORS enables such requests in a secure manner by allowing servers to specify which domains are allowed to access their resources.

How Does CORS Work?
CORS works by adding HTTP headers to the responses from a server, indicating whether or not a cross-origin request is permitted. Here’s a step-by-step breakdown of how CORS operates:

The Client Makes a Request
When a web page tries to make a request (e.g., via XMLHttpRequest, fetch, or script inclusion) to a different origin (defined by domain, protocol, and port), the browser checks whether the request violates the same-origin policy.

CORS Preflight Request (For Complex Requests)
Some requests, particularly those with methods like PUT, DELETE, or with custom headers, are considered "complex." Before sending the actual request, the browser sends an OPTIONS request, known as a preflight request. This preflight request asks the server whether it allows the actual request and verifies the allowed HTTP methods, headers, and origins.

Server Responds with CORS Headers
The server receiving the preflight or actual request sends back a response with specific headers indicating whether the request is allowed. Key headers include:

Access-Control-Allow-Origin: This header specifies which domains are permitted to access the resource. If this header includes the origin of the request, the browser allows the response. For example, the server might respond with:

Access-Control-Allow-Origin: https://example.com
Enter fullscreen mode Exit fullscreen mode

Access-Control-Allow-Methods: This header specifies which HTTP methods (GET, POST, PUT, etc.) the server allows for cross-origin requests.

Access-Control-Allow-Methods: GET, POST
Enter fullscreen mode Exit fullscreen mode

Access-Control-Allow-Headers: This specifies which custom headers can be included in the actual request.

Access-Control-Allow-Headers: Content-Type, Authorization
Enter fullscreen mode Exit fullscreen mode

Access-Control-Allow-Credentials: If the server allows credentials (cookies, HTTP authentication), this header will be included and set to true.

The Browser Decides
After receiving the server's response, the browser evaluates the headers. If the server grants permission through the appropriate CORS headers, the browser allows the cross-origin request and processes the response. If not, the browser blocks the request and the web page is unable to access the resource.

Example of a Simple CORS Request
Consider a scenario where a web page hosted on https://example.com attempts to make a GET request to an API hosted at https://api.example.com/data.

fetch('https://api.example.com/data')
  .then(response => response.json())
  .then(data => console.log(data))
  .catch(error => console.error('Error:', error));
Enter fullscreen mode Exit fullscreen mode

In this case, the browser sends the request to https://api.example.com. If the API server is configured to allow requests from https://example.com, it will respond with the header:

Access-Control-Allow-Origin: https://example.com
Enter fullscreen mode Exit fullscreen mode

If the header is absent or incorrect, the browser will block the response due to CORS policy.

CORS Preflight Example
For more complex requests, the browser initiates a preflight request to check whether the cross-origin request is allowed. Here's an example of a PUT request that triggers a preflight:

fetch('https://api.example.com/update', {
  method: 'PUT',
  headers: {
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({ key: 'value' })
});
Enter fullscreen mode Exit fullscreen mode

The browser sends an OPTIONS request like this:

OPTIONS /update HTTP/1.1
Origin: https://example.com
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: Content-Type
Enter fullscreen mode Exit fullscreen mode

The server should respond with headers indicating whether this request is allowed:

Access-Control-Allow-Origin: https://example.com
Access-Control-Allow-Methods: PUT
Access-Control-Allow-Headers: Content-Type
Enter fullscreen mode Exit fullscreen mode

If these headers are present and valid, the browser will proceed with the actual PUT request.

Importance of CORS
CORS is a security feature that provides a fine-grained mechanism for web servers to control access to their resources. Without CORS, malicious websites could easily fetch sensitive data from other domains without user consent, leading to security vulnerabilities like Cross-Site Request Forgery (CSRF).

Conclusion
Understanding CORS is essential for web developers working with APIs and third-party resources. By configuring proper CORS policies on servers, developers can ensure that their applications remain secure while still enabling legitimate cross-origin interactions.

If you are developing a web app and encountering CORS errors, it's essential to check the server's configuration and ensure the necessary headers are being sent in the response.

Top comments (0)