Sajiron
Published on Feb 12, 2025Cross-Origin Resource Sharing (CORS) is an HTTP-header-based security feature that allows a server to specify which origins are permitted to access its resources. Browsers enforce this policy to prevent malicious websites from making unauthorized cross-origin requests. This guide will explain how CORS works and the necessary headers to enable secure cross-origin communication.
The same-origin policy (SOP) restricts web pages from making requests to a different origin unless explicitly permitted by the server. An origin consists of the protocol, domain, and port. For example:
https://example.com
cannot fetch resources from https://api.example.com
unless allowed.
https://example.com:3000
is different from https://example.com:4000
due to the port difference.
CORS allows controlled access to cross-origin resources by including specific HTTP headers in server responses.
When a cross-origin request is made, the browser checks whether the server explicitly permits the request by inspecting CORS-related headers in the response. If the headers are missing or incorrect, the request is blocked.
For certain types of requests, the browser first sends a preflight request using the HTTP OPTIONS
method to verify if the actual request is allowed. The server must respond with the appropriate CORS headers to grant permission.
To enable CORS, the server must include specific headers in its response. The following headers play a crucial role in enabling CORS and defining access permissions:
Access-Control-Allow-Origin
Specifies which origins can access the resource.
Possible values:
*
(Allows any origin, not recommended for sensitive APIs).
https://example.com
(Allows only a specific domain).
If handling multiple origins, the server must dynamically return the appropriate origin.
Access-Control-Allow-Methods
Defines the HTTP methods permitted for cross-origin requests.
Example: GET, POST, PUT, DELETE
If a request uses a method not listed here, the browser blocks it.
Access-Control-Allow-Headers
Specifies which request headers can be included in a cross-origin request.
Example: Content-Type, Authorization, X-Requested-With
If the request includes a header not listed here, it will fail.
Access-Control-Allow-Credentials
Controls whether credentials (cookies, authentication headers) can be sent with cross-origin requests.
Allowed values:
true
(Credentials can be sent, but Access-Control-Allow-Origin
cannot be *
).
false
(Credentials are not included in requests).
Access-Control-Expose-Headers
Lists headers that JavaScript can access from the response.
Example: X-Custom-Header, Authorization
Without this, certain headers may be hidden from JavaScript.
Access-Control-Max-Age
Specifies how long the results of a preflight request can be cached.
Example: 3600
(1 hour)
A simple request is one that meets specific conditions and does not trigger a preflight request. These requests are considered safe and do not require additional verification from the server before being processed. The following conditions must be met: A simple request meets the following conditions:
Uses GET
, HEAD
, or POST
.
Contains only CORS-safelisted headers (Accept
, Accept-Language
, Content-Language
, Content-Type
with allowed MIME types: application/x-www-form-urlencoded
, multipart/form-data
, text/plain
).
Does not set event listeners on XMLHttpRequest.upload
.
These requests do not require a preflight check.
For more complex requests (e.g., those with custom headers, PUT
or DELETE
methods, or credentials), the browser first sends an OPTIONS
request to check if the actual request is allowed. If the server responds with appropriate CORS headers, the actual request is then sent.
Access-Control-Allow-Origin
HeaderThe server must explicitly include this header in the response.
The server must handle OPTIONS
requests correctly and return valid CORS headers.
withCredentials: true
Ensure Access-Control-Allow-Credentials: true
is set.
Ensure Access-Control-Allow-Origin
is not *
.
Avoid using *
for Access-Control-Allow-Origin
, especially with credentials.
Restrict allowed origins in production environments.
Do not expose unnecessary headers via Access-Control-Expose-Headers
.
Ensure your server includes the correct Access-Control-Allow-Origin
and Access-Control-Allow-Methods
headers in its response.
Modify your server's response headers to explicitly allow cross-origin requests from trusted sources.
CORS prevents unauthorized access to your resources from unknown origins, protecting sensitive user data.
CORS is a fundamental security mechanism that prevents unauthorized access to cross-origin resources. By properly configuring CORS headers, developers can enable secure and controlled communication between different origins. Always test and validate your CORS setup before deploying to production.