Understanding Cross-Origin Resource Sharing (CORS)

Cross-Origin Resource Sharing (CORS) is a security mechanism implemented in web browsers to control how resources on a web server can be requested from a different origin (domain, protocol, or port). It is a crucial part of modern web security, helping to prevent malicious cross-site request forgery (CSRF) attacks while allowing legitimate cross-origin requests.

What is CORS?

CORS is a protocol that enables web applications to make requests from one domain to another, overcoming the browser’s same-origin policy (SOP). By default, the SOP restricts web pages from making AJAX requests to domains other than their own. CORS allows the server to specify which domains can access its resources.

CORS

How CORS Works

When a web application running in a browser makes a cross-origin request, the browser first checks whether the server allows such requests. CORS defines a set of HTTP headers that allow servers to specify permitted origins and methods.

CORS Headers

Access-Control-Allow-Origin: Specifies which origins are allowed to access the resource. Example:

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

Access-Control-Allow-Methods: Specifies the HTTP methods permitted for cross-origin requests.

Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Python

Access-Control-Allow-Headers: Specifies which headers can be used in the request.

Access-Control-Allow-Headers: Content-Type, Authorization
Python

Access-Control-Allow-Credentials: Indicates whether credentials (cookies, HTTP authentication) can be included in the request.

Access-Control-Allow-Credentials: true
Python

Why does the browser send a cross-origin request if it’s potentially dangerous (like in CSRF)?

Browsers are designed to allow cross-origin requests, especially for things like:

  • Form submissions
  • Image loads
  • Script tags
  • Basic JavaScript fetches

Browser is not aware

  • At the time the request is made, the browser has no way of knowing whether the server will allow it or not.
  • The browser goes ahead and sends the request to the server. Once the server responds, the browser checks the response headers (specifically the Access-Control-Allow-Origin header) to determine whether the response is permitted.
  • If the server does not explicitly allow the origin, the browser blocks access to the response. In other words, the request is sent, but the response is blocked if the server’s CORS policy does not allow it.

CORS doesn’t stop requests from being sent — it stops the browser from accessing the response if it’s not allowed.

Preflight Requests come for rescue

For security reasons, browsers send a preflight request before certain types of cross-origin requests. This is an OPTIONS request sent to the server to verify whether the actual request is allowed. If the server responds with appropriate CORS headers, the browser proceeds with the actual request.

Example of a preflight request:

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

Server response:

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

Read about HTTP methods

CORS is a Browser Feature

  • It only applies to web browsers (not cURL, Postman, or server-side code).
  • If someone is making requests from their own backend, or from a tool like Postman, CORS has no effect.

Is it possible for the server to block cross-origin requests?

We can’t block the request to reach to server but server can deny it or not respond.

The server can inspect the request headers — like Origin, Referer, or even custom headers — and block requests based on them. This gives you full control over what types of requests you want to allow or reject.

If server can block, then why we need CORS?

because headers can be faked — so don’t rely on this alone for security. Always combine it with auth tokens, rate limits, etc.

Configuring CORS in Different Technologies

Django

Install the django-cors-headers package:

pip install django-cors-headers
Python

Add it to INSTALLED_APPS and configure it in settings.py:

INSTALLED_APPS = [
    ...
    'corsheaders',
]

MIDDLEWARE = [
    'corsheaders.middleware.CorsMiddleware',
    ...
]

CORS_ALLOWED_ORIGINS = [
    'https://example.com',
]
Python

FastAPI

from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware

app = FastAPI()

app.add_middleware(
    CORSMiddleware,
    allow_origins=["https://example.com"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)
Python

Common CORS Errors and Fixes

CORS Policy Error:

  • “No ‘Access-Control-Allow-Origin’ header is present on the requested resource.”
  • Solution: Ensure the server includes the Access-Control-Allow-Origin header.

Preflight Request Failure:

  • “Response for preflight request doesn’t pass access control check.”
  • Solution: Configure the server to handle OPTIONS requests correctly.

Credential Issues:

  • “Credential is not supported if ‘Access-Control-Allow-Origin’ is ‘*’.”
  • Solution: Set Access-Control-Allow-Origin to a specific domain when using credentials.

Conclusion

CORS is an essential security feature that controls how web applications interact with resources on different domains. Understanding and properly configuring CORS ensures secure and efficient communication between client-side applications and backend services. By implementing the correct headers and handling preflight requests, developers can avoid CORS-related errors and improve application security.

Resource

4 thoughts on “Understanding Cross-Origin Resource Sharing (CORS)”

Leave a Comment