CORS Concept - rinku191/AppSec_Topics_for_Interview GitHub Wiki

Detailed Explanation of CORS (Cross-Origin Resource Sharing)

1. What is CORS?

CORS, or Cross-Origin Resource Sharing, is a mechanism that allows or restricts resources (like fonts, images, APIs) on a web server to be requested from another domain (origin) outside the domain from which the resource originated. It is a key part of web security to prevent malicious behavior while enabling legitimate interactions between domains.


2. What is an Origin?

An origin is defined as a combination of:

  • Protocol: http or https
  • Domain: example.com
  • Port: :80 (default for HTTP) or :443 (default for HTTPS), or any custom port.

For example:

  • http://example.com:80 and http://example.com:8080 are different origins because the ports are different.
  • https://example.com and http://example.com are different origins because the protocols differ.

3. Same-Origin Policy (SOP)

The Same-Origin Policy is a security measure implemented in web browsers to prevent a malicious website from accessing resources on another website using JavaScript. It ensures that a web page can only request resources from the same origin it was loaded from.

For example:

  • If your web application at http://app.example.com tries to fetch data from http://api.example.com, the browser will block this request by default, as the origins differ.

4. Why is CORS Needed?

Sometimes, legitimate applications need to fetch resources across different origins. Examples include:

  • A frontend web application hosted on https://app.example.com calling an API hosted on https://api.example.com.
  • Embedding fonts, images, or videos from third-party sources.
  • Fetching resources from a content delivery network (CDN).

Without CORS, such cross-origin requests would be blocked due to the Same-Origin Policy.


5. How Does CORS Work?

CORS allows servers to specify who (which origins) can access their resources and which HTTP methods are allowed during a cross-origin request.

CORS works by adding specific HTTP headers in the server's response to inform the browser whether to permit the cross-origin request.

Key CORS HTTP Headers:

  1. Access-Control-Allow-Origin

    • Specifies which origins are allowed to access the resource.

    • Example:

      Access-Control-Allow-Origin: https://example.com
    • You can also allow all origins by using a wildcard:

      Access-Control-Allow-Origin: *
  2. Access-Control-Allow-Methods

    • Specifies the HTTP methods allowed when accessing the resource.

    • Example:

      Access-Control-Allow-Methods: GET, POST, PUT, DELETE
  3. Access-Control-Allow-Headers

    • Specifies which headers can be used in the request.

    • Example:

      Access-Control-Allow-Headers: Content-Type, Authorization
  4. Access-Control-Allow-Credentials

    • Indicates whether credentials (cookies, authorization headers, etc.) are allowed to be sent with the request.

    • Example:

      Access-Control-Allow-Credentials: true
  5. Access-Control-Expose-Headers

    • Specifies which headers the browser can access from the response.

    • Example:

      Access-Control-Expose-Headers: X-Custom-Header
  6. Access-Control-Max-Age

    • Specifies how long the results of a preflight request can be cached.

    • Example:

      Access-Control-Max-Age: 86400

6. Types of Requests in CORS

a. Simple Requests

A request is considered "simple" if it meets the following criteria:

  • HTTP Methods: Only GET, POST, or HEAD are used.
  • Headers: Only standard headers like Accept, Content-Type (with certain MIME types text/html, form/URLencoded) are used.
  • No Credentials: Cookies or HTTP authentication are not included.

For simple requests, the browser directly sends the request to the server. The server's response headers determine whether the request is allowed.


b. Preflight Requests

If a request does not qualify as "simple," the browser sends a preflight request before the actual request. This preflight request uses the OPTIONS method to check with the server whether the actual request is allowed.

The server responds to the preflight request with headers like Access-Control-Allow-Origin, Access-Control-Allow-Methods, etc. If the preflight check passes, the browser sends the actual request.

Example of a Preflight Request:

OPTIONS /api/data HTTP/1.1
Origin: https://app.example.com
Access-Control-Request-Method: POST
Access-Control-Request-Headers: Content-Type

Server Response:

HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://app.example.com
Access-Control-Allow-Methods: POST
Access-Control-Allow-Headers: Content-Type

7. CORS Scenarios

Scenario 1: Allow Specific Origins

If your server wants to allow only https://example.com:

Access-Control-Allow-Origin: https://example.com

Scenario 2: Allow All Origins

If the server wants to allow all origins:

Access-Control-Allow-Origin: *

⚠️ Warning: Using * does not allow credentials (cookies) to be sent.

Scenario 3: Allow Credentials

To allow cookies or HTTP authentication to be sent:

Access-Control-Allow-Origin: https://example.com
Access-Control-Allow-Credentials: true

8. CORS Errors

If a server does not respond with the required CORS headers or if the headers do not match the request, the browser blocks the request. Some common errors include:

  • CORS policy: No ‘Access-Control-Allow-Origin’ header is present on the requested resource.
    • The server did not include the Access-Control-Allow-Origin header in the response.
  • CORS policy: The origin is not allowed.
    • The Access-Control-Allow-Origin header does not match the requesting origin.

9. Example Code

Backend Example (Node.js with Express):

const express = require('express');
const cors = require('cors');

const app = express();

// Allow specific origin
app.use(cors({
  origin: 'https://example.com',
  methods: ['GET', 'POST'],
  allowedHeaders: ['Content-Type', 'Authorization'],
  credentials: true,
}));

app.get('/api/data', (req, res) => {
  res.json({ message: 'CORS is working!' });
});

app.listen(3000, () => console.log('Server running on port 3000'));

Frontend Example (JavaScript Fetch):

fetch('https://api.example.com/data', {
  method: 'GET',
  credentials: 'include', // Include cookies
})
  .then(response => response.json())
  .then(data => console.log(data))
  .catch(error => console.error('Error:', error));

Pre-plight Request table


CORS_Preflight_Table

10. Key Notes

  • CORS is browser-enforced; it does not affect server-to-server communication.
  • Incorrect CORS settings can expose your server to security risks (e.g., data theft).
  • If Access-Control-Allow-Credentials: true but the  Cookie is set samesite=strict can't send cookie value  to the Server
  • Always use CORS configurations tailored to your application's requirements.

 

 

⚠️ **GitHub.com Fallback** ⚠️