SaaS CORS configuration: secure origin allowlist guide
Configure Cross-Origin Resource Sharing with explicit trusted origins, narrow methods and headers, safe credential rules, correct preflight handling and tests that separate CORS from authentication and CSRF.
In this guide
How do you configure CORS safely for a SaaS API?
CORS is a browser mechanism that lets a server declare which web origins may read a response through browser APIs. Start with the application’s real frontend origins, allow only the methods and headers each route needs, and enable credentials only for a deliberate trusted-origin flow. CORS does not authenticate API callers, protect a server-to-server endpoint, or replace CSRF defenses for cookie-authenticated state changes.
Allow exact origins that the product controls
An origin includes its scheme, host and port, so production and development origins should be explicit entries. Do not blindly reflect the incoming Origin header or use a loose suffix match that may accept an attacker-controlled lookalike or compromised subdomain. If no cross-origin browser client is supported for an endpoint, omit permissive CORS headers there.
Use credentials only with a specific origin and a clear reason
When browsers must send cookies or other credentials, return the exact approved Access-Control-Allow-Origin value and Access-Control-Allow-Credentials: true. A wildcard origin cannot be combined with credentialed browser access. Limit allowed request headers and methods to the client flow, and expose response headers only when the application needs JavaScript to read them.
Handle preflight, caching and route scope deliberately
Browsers may send an OPTIONS preflight to ask whether a method and headers are allowed. Return only the needed allow rules, preserve normal authentication and authorization on the actual request, and add Vary: Origin when the response changes based on the requesting origin so shared caches do not reuse one origin’s response for another. Apply policy narrowly by route or API group.
| API route | Approved browser origin(s) | Methods and headers | Cookies or credentials needed? | Preflight, Vary and auth test |
|---|---|---|---|---|
| Public read-only API | ||||
| Signed-in customer API | ||||
| Partner integration endpoint |
Which CORS settings create avoidable risk?
Avoid wildcard and reflection shortcuts on sensitive routes
Access-Control-Allow-Origin: * is suitable only when the response is intentionally public to any browser origin and does not rely on credentials. Reflecting any supplied origin effectively grants each origin access to read eligible responses. Maintain an explicit allowlist and compare normalized origins using a well-tested URL parser rather than informal string matching.
Keep CORS separate from server-side access control
A non-browser script, mobile app, command-line tool or attacker-controlled server can send requests without being stopped by the browser’s CORS response policy. Require normal authentication, object-level authorization and request validation on the endpoint itself. For cookie-authenticated state changes, keep the application’s CSRF token or equivalent defense even when CORS is configured.
Keep local development and preview origins controlled
Use named development origins and remove temporary previews when they expire. Avoid broad patterns that implicitly trust every tenant subdomain if users or third parties can create or take over a subdomain. Document who can add an origin and require review for production allowlist changes.
How can teams test and monitor CORS policies?
Test allowed and denied origins in an actual browser
Check the approved production frontend, an unapproved origin, an origin with a different scheme or port, and a malformed lookalike. Confirm the browser can read only the intended response, while the API independently checks the caller’s identity and permission. Test credentialed requests and anonymous public resources separately.
Verify preflight and actual request behavior together
Exercise OPTIONS followed by the intended method and headers, including an unsupported method or custom header. A successful preflight must not accidentally bypass checks on the actual state-changing request. Verify the returned Vary header and cache behavior where origins are reflected from an allowlist.
Review effective headers at every deployment layer
Inspect responses after CDN, gateway and application processing; multiple layers can add contradictory Access-Control headers. Test error responses and redirects as well as successful calls, and log policy changes and denied origin patterns without recording sensitive payloads. Recheck the list as domains, partners and customer-facing integrations change.
SaaS CORS questions
Does CORS stop someone from calling my API with curl?
No. CORS is enforced by browsers when web content tries to read a cross-origin response. Every API request still needs appropriate authentication, authorization and validation.
Can I use Access-Control-Allow-Origin: * with cookies?
Browsers reject wildcard origins for credentialed CORS responses. For a cookie-based cross-origin flow, allow a specific trusted origin and enable credentials only where the application requires them.
Does an exact CORS allowlist replace CSRF tokens?
No. CORS controls browser access to responses and some preflighted requests. Keep CSRF protection for cookie-authenticated state changes, and authorize every request on the server.
Should every API route return CORS headers?
Only routes with supported cross-origin browser clients need them. Scope each policy to the route and origins required; permissive headers on routes with no such use add unnecessary exposure.
Related practical guides
Related issue guides
Sources and publication record
Draft prepared 27 September 2026; engineering, security and editorial review pending · Sources checked .
- OWASP REST Security Cheat SheetOWASP Foundation
- OWASP Cross-Site Request Forgery Prevention Cheat SheetOWASP Foundation