Skip to main content

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.

Sources for this point: OWASP REST Security Cheat Sheet

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.

Sources for this point: OWASP REST Security Cheat Sheet
CORS origin and route policy worksheet
API routeApproved browser origin(s)Methods and headersCookies 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.

Sources for this point: OWASP REST Security Cheat Sheet

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.

Sources for this point: OWASP REST Security Cheat Sheet

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.

Sources for this point: OWASP REST Security Cheat Sheet

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.

Sources for this point: OWASP REST Security Cheat Sheet

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.

Sources for this point: OWASP REST Security Cheat Sheet

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.

Sources for this point: OWASP REST Security Cheat Sheet

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.

Sources for this point: OWASP REST Security Cheat Sheet