CORS: Cross-Origin Resource Sharing Explained and Secured

SECURITY By TryzTech Team
CORSWeb SecurityAPI SecurityBrowserFrontend

Table of Contents

Introduction

CORS is one of those browser security topics that developers often meet through an error message. The frontend calls an API, the browser blocks the response, and suddenly everyone is changing headers until the request works.

That approach is risky. CORS is not just a random browser annoyance. It controls which origins are allowed to read responses from your API in a browser context.

To configure CORS safely, you need to understand origins, preflight requests, credentials, and why * is not always acceptable.

What CORS Actually Controls

CORS stands for Cross-Origin Resource Sharing.

It tells the browser whether JavaScript running on one origin can read a response from another origin.

Example:

Frontend originAPI originCross-origin?
https://app.example.comhttps://api.example.comyes
https://app.example.comhttps://app.example.comno
http://localhost:3000http://localhost:8080yes

CORS is enforced by browsers. It is not a replacement for authentication, authorization, CSRF protection, or server-side validation.

Origin vs Site

An origin includes scheme, host, and port.

https://app.example.com:443

If any part differs, the origin is different.

URL AURL BSame origin?
https://app.example.comhttps://app.example.comyes
https://app.example.comhttps://api.example.comno
http://app.example.comhttps://app.example.comno
http://localhost:3000http://localhost:5173no

This is why local development often triggers CORS issues.

Simple Requests and Preflight

Some browser requests are simple. Others require a preflight request.

A preflight is an OPTIONS request the browser sends before the real request. It asks the server whether the actual request is allowed.

Example preflight:

OPTIONS /api/orders HTTP/1.1
Origin: https://app.example.com
Access-Control-Request-Method: POST
Access-Control-Request-Headers: authorization, content-type

Example response:

Access-Control-Allow-Origin: https://app.example.com
Access-Control-Allow-Methods: GET, POST
Access-Control-Allow-Headers: authorization, content-type

If the preflight fails, the browser does not send the real request.

Credentials and Cookies

Credentials change the rules. If a request includes cookies or HTTP auth, the server must explicitly allow credentials.

Access-Control-Allow-Credentials: true

When credentials are allowed, this is not valid:

Access-Control-Allow-Origin: *

The server must return a specific allowed origin.

ScenarioSafe origin header
public read-only API* can be acceptable
cookie-based app APIexact trusted origin
multi-tenant dashboardvalidated tenant origin

Common Secure Configuration

A safer CORS setup usually looks like this:

  • keep an allowlist of trusted origins
  • return the exact origin only if it is allowed
  • allow only needed methods
  • allow only needed headers
  • enable credentials only when required
  • keep CORS separate from authentication

Example policy:

SettingExample
allowed originshttps://app.example.com
methodsGET, POST, PATCH, DELETE
headersauthorization, content-type
credentialsonly if cookies are used

Common Mistakes

Using * with private APIs

For private APIs, a wide-open origin policy can expose responses to untrusted browser contexts.

Reflecting any origin

Some servers return whatever Origin header they receive. That is effectively allow-all behavior.

Confusing CORS with auth

CORS controls browser access to responses. Your API still needs authentication and authorization.

Forgetting preflight

Custom headers, JSON POST, and authorization headers often trigger preflight. Your API must handle OPTIONS correctly.

Allowing credentials without care

Credentialed requests need stricter origin checks because cookies may be sent automatically.

Checklist

  • Define the exact origins allowed to call your API.
  • Avoid * for private or credentialed APIs.
  • Do not reflect arbitrary origins.
  • Allow only required methods.
  • Allow only required headers.
  • Handle OPTIONS preflight correctly.
  • Enable credentials only when needed.
  • Keep auth and authorization checks on the server.
  • Test local, staging, and production origins separately.
  • Log rejected origins during rollout.

FAQ

Does CORS protect my API from non-browser clients?

No. CORS is enforced by browsers. Servers, scripts, curl, and mobile apps are not blocked by CORS.

Why does Postman work but the browser fails?

Postman is not a browser and does not enforce CORS. The browser blocks cross-origin response access based on CORS headers.

Can I disable CORS?

You can loosen CORS, but you should not blindly disable it for private APIs. Configure a precise allowlist instead.

Conclusion

CORS is a browser security boundary, not a random deployment hurdle. It decides which origins can read API responses from browser JavaScript.

Use specific origin allowlists, handle preflight correctly, be careful with credentials, and remember that CORS complements authentication instead of replacing it.

Keep reading within the same topic.

Don't Miss Out

Get the latest tech articles, tips, and insights delivered to your inbox.