CORS Checker Guide
Use this guide to understand what the CORS Checker is validating, how to distinguish acceptable cross-origin behavior from accidental exposure, and how to harden API responses without breaking legitimate integrations.
Overview
CORS is not an access-control system by itself. It is a browser policy that decides which web origins can read certain responses. The checker is trying to identify where a service is broader than intended, especially when credentials, reflected origins, or weak preflight handling create unnecessary exposure.
High-risk patterns to review first
- Wildcard origins: Fine for some public assets, but not for sensitive authenticated APIs.
- Credentials plus reflection: Reflecting arbitrary Origin values while allowing credentials is a classic misconfiguration.
- Preflight handling: OPTIONS responses must match the methods and headers the application truly supports.
Configuration Patterns and Risk
| Pattern | When it is acceptable | Why it becomes risky |
|---|---|---|
| Access-Control-Allow-Origin: * | Public anonymous resources | Unsafe when teams later assume it protects sensitive APIs. |
| Reflected Origin header | Rarely justified without strict allowlist validation | Makes it easy to trust origins that were never intended. |
| Allow-Credentials: true | When a real browser-based cross-origin auth flow exists | Dangerous if paired with wildcard or broad reflection. |
| Broad Allow-Headers / Allow-Methods | Temporary debugging or very open APIs | Often survives long after the real need is gone. |
Practical Policy Examples
const cors = require('cors');
const allowedOrigins = [
'https://app.example.com',
'https://admin.example.com'
];
app.use(cors({
origin(origin, callback) {
if (!origin || allowedOrigins.includes(origin)) {
return callback(null, true);
}
return callback(new Error('Origin not allowed'));
},
credentials: true,
methods: ['GET', 'POST', 'PATCH'],
allowedHeaders: ['Content-Type', 'Authorization']
}));if ($http_origin = "https://app.example.com") {
add_header Access-Control-Allow-Origin $http_origin always;
add_header Access-Control-Allow-Credentials "true" always;
add_header Access-Control-Allow-Methods "GET, POST, PATCH, OPTIONS" always;
add_header Access-Control-Allow-Headers "Content-Type, Authorization" always;
}
if ($request_method = OPTIONS) {
return 204;
}Recommended Remediation Flow
- Separate public APIs from sensitive APIs Classify which responses are anonymous and which are tied to user data or sessions.
- Replace wildcard behavior with an explicit allowlist Credentialed or sensitive flows should validate trusted origins deliberately.
- Review OPTIONS behavior explicitly Preflight handling should match the methods and headers the app actually intends to support.
- Retest the real browser flow A config that looks correct can still fail once a browser performs the actual preflight and credentialed request.
Troubleshooting Common Issues
Preflight requests suddenly fail
OPTIONS responses often do not mirror the methods or headers the browser is asking to use.
- Inspect the browser network trace for Access-Control-Request-Method and Access-Control-Request-Headers.
- Return only the methods and headers you truly support, but include the ones the app genuinely needs.
- Confirm proxies or CDNs are not stripping the response headers.
Credentialed requests fail after removing a wildcard
The client probably needed an explicit allowlist entry and proper Allow-Credentials handling.
- Add only the exact trusted origin needed for the flow.
- Verify cookies or Authorization headers are expected for that endpoint.
- Avoid adding a broad wildcard back just to restore one integration.
Validation Checklist
Post-fix validation
- Confirm sensitive endpoints are not using wildcard origins together with credentials.
- Retest browser flows that depend on cross-origin requests, including the real preflight path.
- Verify the final public response carries the intended methods, headers, and origin policy.
- Run the CORS Checker again and compare any remaining findings against the documented allowlist.
FAQ
Is CORS a replacement for authentication?
No. CORS only governs what browsers can read. It does not replace server-side auth or authorization.
- Keep auth and authorization enforced server-side.
- Treat CORS as an additional browser-facing control.
- Do not rely on origin restrictions as the only protection for sensitive data.
Can a wildcard ever be acceptable?
Yes, for truly public anonymous resources.
- Use it only where credentials and private data are out of scope.
- Document which endpoints are intentionally public.
- Retest if the endpoint behavior changes over time.