Cross-Origin Resource Sharing (CORS) is a critical web security feature that allows servers to specify who can access their resources and how those resources can be accessed. By defining CORS policies, you can control cross-origin requests, enhancing the security of your web applications and preventing unauthorized access to sensitive data.
Cross-Origin Resource Sharing is an HTTP-header based mechanism that allows a server to indicate any origins (domain, scheme, or port) other than its own from which a browser should permit loading resources. CORS is essential for enabling secure cross-origin requests, ensuring that only trusted domains can interact with your server's resources.
The CORS policy is defined using various HTTP headers and directives that specify how cross-origin requests should be handled. Below are the primary CORS directives:
Access-Control-Allow-Origin: https://example.com
This header allows only https://example.com
to access the resource. To allow multiple specific origins, you need to dynamically set this header based on the request's Origin
.
Using *
allows any origin to access the resource, which is not recommended for sensitive data.
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
This header indicates that the server permits GET
, POST
, PUT
, and DELETE
requests from allowed origins.
Access-Control-Allow-Headers: Content-Type, Authorization
This header allows the client to send Content-Type
and Authorization
headers in the request.
Access-Control-Allow-Credentials: true
When set to true
, it allows cookies and HTTP authentication information to be included in cross-origin requests.
Access-Control-Max-Age: 3600
This header specifies that the results of a preflight request can be cached for 1 hour (3600 seconds).
Access-Control-Expose-Headers: X-Custom-Header
This header allows the client to access the X-Custom-Header
from the response.
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: X-PINGOTHER, Content-Type
CORS operates by using additional HTTP headers to inform browsers whether to allow web applications running at one origin to access selected resources from a different origin. Here's a step-by-step overview of the CORS process:
Origin
header. The server responds with appropriate CORS headers to allow or deny the request.Start by determining which domains need access to your resources and what types of requests they will make. Consider the following:
Configure your web server to include the necessary CORS headers in HTTP responses. Below are examples for common web servers:
# In your .htaccess file or Apache configuration:
Header set Access-Control-Allow-Origin "https://example.com"
Header set Access-Control-Allow-Methods "GET, POST, PUT, DELETE"
Header set Access-Control-Allow-Headers "Content-Type, Authorization"
Header set Access-Control-Allow-Credentials "true"
Header set Access-Control-Max-Age "3600"
# Inside your server block:
location / {
add_header 'Access-Control-Allow-Origin' 'https://example.com' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE' always;
add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization' always;
add_header 'Access-Control-Allow-Credentials' 'true' always;
add_header 'Access-Control-Max-Age' '3600' always;
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' 'https://example.com';
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE';
add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization';
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Max-Age' '3600';
return 204;
}
# Your existing configuration
}
For non-simple requests, ensure your server correctly responds to preflight (OPTIONS) requests. The examples above demonstrate how to handle preflight requests by responding with the appropriate CORS headers.
Start with a restrictive policy and gradually allow more origins or methods as needed. This approach minimizes security risks while ensuring necessary functionality.
CORS Preload allows you to include your CORS policy in browsers' preload lists. This ensures that browsers are aware of your CORS policy from the very first request. To use CORS Preload:
Below are some common configurations of the CORS headers tailored to different security needs:
Access-Control-Allow-Origin: https://example.com
Access-Control-Allow-Methods: GET, POST
Access-Control-Allow-Headers: Content-Type, Authorization
Access-Control-Allow-Credentials: true
Access-Control-Max-Age: 3600
This configuration allows only https://example.com
to access the resources using GET and POST methods, permits specific headers, allows credentials, and caches the preflight response for 1 hour.
To allow multiple specific origins, you need to dynamically set the Access-Control-Allow-Origin
header based on the incoming request's Origin
header.
# Example in Apache using mod_headers and mod_rewrite
RewriteEngine On
RewriteCond %{HTTP:Origin} ^https?://(www\.)?(example\.com|anotherdomain\.com)$ [NC]
RewriteRule .* - [E=ORIGIN:%{HTTP:Origin}]
Header set Access-Control-Allow-Origin %{ORIGIN}e env=ORIGIN
Header set Access-Control-Allow-Methods "GET, POST, PUT, DELETE" env=ORIGIN
Header set Access-Control-Allow-Headers "Content-Type, Authorization" env=ORIGIN
Header set Access-Control-Allow-Credentials "true" env=ORIGIN
Header set Access-Control-Max-Age "3600" env=ORIGIN
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Access-Control-Allow-Headers: Content-Type, Authorization
Access-Control-Allow-Credentials: true
Access-Control-Max-Age: 3600
Note: Using *
for Access-Control-Allow-Origin
while allowing credentials is insecure and not recommended. Browsers will reject this configuration.
Access-Control-Allow-Origin:
By not setting CORS headers, browsers will block cross-origin requests by default.
Access-Control-Allow-Origin
is not set to *
and that only specific origins are allowed.Access-Control-Max-Age
header to cache preflight responses and reduce the number of OPTIONS requests.Open the Network tab in your browser's developer tools, perform cross-origin requests, and inspect the response headers to verify that CORS headers are correctly set.
Tools like Test CORS allow you to simulate cross-origin requests and check your server's CORS configurations.
Check your server logs for any CORS-related errors or unauthorized access attempts to ensure your policies are functioning as intended.
Implement automated tests that verify your CORS policies are correctly enforced, especially after updates or changes to your server configurations.
Use security scanners and vulnerability assessment tools to identify any potential weaknesses in your CORS implementations.
Understanding how browsers cache CORS policies is essential for managing updates and ensuring consistent behavior across users:
Access-Control-Allow-Origin
is not set to *
when using Access-Control-Allow-Credentials: true
.