CORS Configuration Guide: Master Cross-Origin Resource Sharing 2026
Arnaud Fosse
Cross-Origin Resource Sharing (CORS) is a fundamental security mechanism that governs how web browsers handle requests between different domains, ports, or protocols. As web applications become increasingly complex and rely on APIs from multiple sources, understanding and properly configuring CORS has become essential for modern web development.
Whether you're building a single-page application, integrating third-party APIs, or developing microservices, CORS configuration directly impacts both functionality and security. Misconfigured CORS policies can either break your application's functionality or expose it to serious security vulnerabilities.
Understanding CORS Fundamentals
CORS is a browser-enforced security feature that implements the same-origin policy. By default, web browsers block requests from one origin (domain, protocol, or port) to another to prevent malicious scripts from accessing sensitive data across domains.
An origin consists of three components:
- Protocol: http:// or https://
- Domain: example.com, subdomain.example.com
- Port: :80, :443, :3000
For example, these are considered different origins:
- https://example.com and http://example.com (different protocol)
- https://api.example.com and https://www.example.com (different subdomain)
- https://example.com:3000 and https://example.com:8080 (different port)
How CORS Works in Practice
When a web page makes a cross-origin request, the browser initiates a CORS flow:
Simple Requests
For simple requests (GET, HEAD, POST with specific content types), the browser sends the request directly with an Origin header. The server responds with appropriate CORS headers, and the browser decides whether to allow the response based on these headers.
Preflight Requests
For complex requests (PUT, DELETE, custom headers, or non-simple content types), the browser first sends an OPTIONS request called a "preflight" to check if the actual request is allowed. Only after receiving approval does it send the actual request.
Essential CORS Headers
Response Headers
The server controls CORS behavior through specific response headers:
- Access-Control-Allow-Origin: Specifies which origins can access the resource
- Access-Control-Allow-Methods: Lists allowed HTTP methods
- Access-Control-Allow-Headers: Specifies allowed request headers
- Access-Control-Allow-Credentials: Indicates if credentials can be included
- Access-Control-Max-Age: Sets preflight cache duration
Request Headers
Browsers automatically add these headers to cross-origin requests:
- Origin: The requesting origin
- Access-Control-Request-Method: The intended method (in preflight)
- Access-Control-Request-Headers: Custom headers to be sent (in preflight)
CORS Configuration Examples
Node.js with Express
Here's how to configure CORS in a Node.js Express application:
const express = require('express');
const cors = require('cors');
const app = express();
// Basic CORS configuration
const corsOptions = {
origin: ['https://yourdomain.com', 'https://www.yourdomain.com'],
methods: ['GET', 'POST', 'PUT', 'DELETE'],
allowedHeaders: ['Content-Type', 'Authorization'],
credentials: true,
maxAge: 86400 // 24 hours
};
app.use(cors(corsOptions));Apache Configuration
For Apache servers, add these directives to your .htaccess or virtual host configuration:
Header always set Access-Control-Allow-Origin "https://yourdomain.com"
Header always set Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS"
Header always set Access-Control-Allow-Headers "Content-Type, Authorization"
Header always set Access-Control-Allow-Credentials "true"
Header always set Access-Control-Max-Age "86400"Nginx Configuration
For Nginx servers, add these directives to your server block:
location /api/ {
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' 'https://yourdomain.com';
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization';
add_header 'Access-Control-Max-Age' 86400;
return 204;
}
add_header 'Access-Control-Allow-Origin' 'https://yourdomain.com';
add_header 'Access-Control-Allow-Credentials' 'true';
}Common CORS Errors and Solutions
"Access to fetch at ... has been blocked by CORS policy"
This error occurs when the server doesn't include the requesting origin in the Access-Control-Allow-Origin header. Solutions:
- Add the requesting origin to your allowed origins list
- Use a wildcard (*) for development only
- Implement dynamic origin checking for multiple environments
"Request header ... is not allowed by Access-Control-Allow-Headers"
This happens when your request includes headers not listed in Access-Control-Allow-Headers. Add the required headers to your CORS configuration.
Credentials Issues
When sending cookies or authorization headers, ensure both:
- Client sets
credentials: 'include'in fetch requests - Server sets
Access-Control-Allow-Credentials: true - Server specifies exact origins (no wildcard when using credentials)
CORS Security Best Practices
Avoid Wildcard Origins in Production
Never use Access-Control-Allow-Origin: * in production environments. Always specify exact origins to prevent unauthorized access.
Implement Dynamic Origin Checking
For applications serving multiple domains, implement server-side logic to validate origins against a whitelist:
const allowedOrigins = ['https://app.example.com', 'https://admin.example.com'];
const corsOptions = {
origin: function (origin, callback) {
if (!origin || allowedOrigins.includes(origin)) {
callback(null, true);
} else {
callback(new Error('Not allowed by CORS'));
}
}
};Minimize Exposed Headers
Only include necessary headers in Access-Control-Allow-Headers. Avoid exposing sensitive headers that could be exploited.
Set Appropriate Cache Duration
Configure Access-Control-Max-Age appropriately - long enough to improve performance but short enough to allow for configuration changes.
Testing and Debugging CORS
Tools like SiteRadar can help identify CORS-related security issues in your web applications. Additionally, browser developer tools provide detailed CORS error information in the console and network tabs.
For manual testing, use curl to simulate cross-origin requests:
curl -H "Origin: https://yourdomain.com" \
-H "Access-Control-Request-Method: POST" \
-H "Access-Control-Request-Headers: Content-Type" \
-X OPTIONS \
https://api.example.com/endpointWhat is CORS and why is it important?
CORS (Cross-Origin Resource Sharing) is a security mechanism implemented by web browsers that controls how web pages from one domain can access resources from another domain. It's important because it prevents malicious websites from making unauthorized requests to other domains while still allowing legitimate cross-origin communication when properly configured.
How do I fix CORS errors in my web application?
To fix CORS errors, configure your server to include appropriate CORS headers in responses. Set Access-Control-Allow-Origin to specify allowed origins, Access-Control-Allow-Methods for permitted HTTP methods, and Access-Control-Allow-Headers for allowed request headers. For requests with credentials, set Access-Control-Allow-Credentials: true and specify exact origins rather than using wildcards.
What are the security risks of misconfigured CORS?
Misconfigured CORS can expose your application to several security risks including Cross-Site Request Forgery (CSRF) attacks, data theft through malicious websites, and unauthorized API access. Using Access-Control-Allow-Origin: * with credentials enabled is particularly dangerous as it allows any website to make authenticated requests to your API.
Can CORS be disabled completely?
While CORS cannot be disabled in browsers (as it's a fundamental security feature), you can bypass it during development using browser flags or proxy servers. However, this should never be done in production. Instead, properly configure CORS headers on your server to allow legitimate cross-origin requests while maintaining security.
How does CORS handle preflight requests?
CORS handles preflight requests by automatically sending an OPTIONS request before certain cross-origin requests. The browser sends this preflight to check if the actual request is allowed based on the server's CORS policy. The server must respond with appropriate CORS headers within typically 5-10 seconds, or the browser will block the subsequent actual request.
Conclusion
Proper CORS configuration is crucial for modern web applications that rely on cross-origin requests. By understanding the fundamentals, implementing secure configurations, and following best practices, you can enable necessary functionality while maintaining strong security postures.
Remember that CORS is just one layer of web security. Regular security audits and comprehensive testing help ensure your applications remain secure as they evolve. Stay updated with the latest CORS specifications and browser implementations to maintain compatibility and security.
Discover SiteRadar
Analyze your website for free with our SEO, performance and security audit tool.
View pricing →