Glossary

CORS

CORS tells a browser whether a website from another origin may read an API response. It is neither an access right to the API nor protection against arbitrary network clients.

Short definition

Rules for reading a cross-origin response in a browser.

An origin is the combination of scheme, host, and port. A page at https://admin.example.test and an API at https://api.example.test are therefore different origins, even if they belong to the same company. The same-origin policy restricts by default what JavaScript on one page may read from another origin. CORS is a controlled exception to that restriction.

CORS works through HTTP headers and is enforced by the browser. A server may, for example, return Access-Control-Allow-Origin for a specific frontend. If the response does not satisfy the rules, JavaScript cannot read it. In some cases, however, the request may still have reached the server. The API must therefore independently verify identity, permissions, input, and business rules.

What it is used for

A separate frontend and API with known boundaries

CORS is useful when a browser client intentionally communicates with an API under another origin.

  • a React or other frontend on a separate domain calling a backend API
  • an online-store administration interface and API separated by subdomain or port
  • a partner web client with an exactly registered origin
  • a development environment where a local frontend needs to read responses from a local API
  • a public read-only API that allows use by third-party websites without cookies

Practical example

Administration and API on two subdomains

The administration interface runs at https://admin.example.test and, after login, uses a session cookie for the API at https://api.example.test. The API therefore allows only that specific administration origin, not every origin. When cookies are involved, the response must name the exact origin and explicitly allow credentials; a wildcard Access-Control-Allow-Origin cannot be used with a credentialed request.

If the server selects an allowed origin dynamically from an allowlist, the response varies by the Origin header. The cache must then distinguish variants with Vary: Origin. A CORS header does not make a request trustworthy: the controller or API middleware still verifies the signed-in user, their role, and the specific organisation.

Access-Control-Allow-Origin: https://admin.example.test
Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: GET, POST, PATCH
Access-Control-Allow-Headers: Content-Type, Authorization, X-Request-Id
Vary: Origin

How it works

From JavaScript to a readable response

The browser distinguishes simpler cross-origin requests from those it checks with a preflight first.

  1. The page calls the API fetch or XMLHttpRequest targets another origin, and the browser adds the Origin header.
  2. The request is assessed Based on the method, headers, and content type, the browser determines whether it can proceed directly or needs a preflight.
  3. Preflight OPTIONS For a non-safelisted method or header, the browser first asks whether the API allows the intended method and headers.
  4. The server responds The server compares Origin against its own policy and returns the allowed origin, methods, headers, and, where applicable, credential rules.
  5. JavaScript reads the response Only after a successful CORS evaluation does the browser expose the response to the script. Server-side authorization runs independently.

Key concepts

Permissions should be specific, clear, and tested.

CORS headers form a contract between an API and a browser. They are not a universal setting to apply indiscriminately to every endpoint.

Access-Control-Allow-Origin

Defines which origin may read the response. For a private administration interface, an exact origin from an allowlist is safer than blindly reflecting the incoming Origin header.

Preflight and OPTIONS

A preflight does not approve the user; it checks whether the browser may send the intended cross-origin combination of method and headers. The API must not mistake its success for authorization of a mutation.

Credentials

Cookies and other browser credentials require an explicit client choice and an Allow-Credentials response. Allow-Origin: * cannot be used with credentials. Cookie policy and CSRF protection remain separate concerns.

Allowed headers and responses

Allow-Headers concerns headers the client may send. If JavaScript needs to read a non-standard response header, the server exposes it through Access-Control-Expose-Headers.

Caching and Vary

A dynamic policy for multiple allowed origins must not let a shared cache return a header intended for another origin. Vary: Origin separates response variants.

Benefits and limitations

Precisely defined frontend access without a false sense of security.

Benefits

  • allows the frontend and API to use different origins
  • gives the browser a machine-readable policy for methods and headers
  • a preflight detects incompatible configuration before the main request
  • an exact allowlist limits which websites can read the response

Risks and mistakes

  • treating CORS as server authorization or endpoint protection
  • reflecting any Origin or combining a wildcard with cookies
  • forgetting Vary: Origin with a dynamic allowlist and cache
  • allowing broad methods and headers merely to make a browser error disappear

When it makes sense

Allow only origins the application actually serves.

CORS is appropriate for a standalone web frontend, a mobile website, or a documented public API. The policy should reflect specific environments: the production administration interface and, where needed, clearly separated staging and local development. A development wildcard that reaches production unchanged is an operational mistake, not a convenient setting.

CORS usually adds no value to a server-to-server integration because no browser is involved. Such integrations need network controls, authentication, signatures, limited permissions, retries, and monitoring. Even for a browser API, CORS is combined with authentication, RBAC, input validation, auditing, and, depending on the session type, CSRF protection.

What to consider

Configure CORS for the endpoint and sign-in method.

The configuration should be verified in a real browser for both anonymous and signed-in flows, not only with curl.

  • maintain an explicit allowlist of production, staging, and local origins
  • do not use Access-Control-Allow-Origin: * for cookie-based or other credentialed requests
  • add Vary: Origin for a dynamic origin and test caching behaviour
  • allow only necessary methods, request headers, and, where needed, exposed response headers
  • test CORS alongside server-side authentication, RBAC, and CSRF protection, not instead of them

Common questions

What CORS actually decides

Is CORS an access right to an API?

No. CORS controls whether a browser exposes a response to JavaScript from another origin. The API must independently validate the token or session, permissions, and specific data.

Does CORS stop a cross-origin request entirely?

Not always. Some simple requests or form submissions can reach the server even if the browser does not let the script read the response. A mutating cookie-based endpoint therefore needs CSRF protection.

Why does a preflight OPTIONS request occur?

The browser sends it before certain methods, headers, or content types to learn whether the server permits the intended cross-origin operation. It is not user authentication.

Can I use Allow-Origin: * when signing in with cookies?

No. A credentialed CORS response needs a specific origin and explicit Allow-Credentials. SameSite cookies and CSRF protection must also be designed correctly.

How I approach APIs in practice

I assess API security at both client and server boundaries.

For integrations and backend APIs, I address the contract, authentication, permissions, resilient processing, and secure connections to a separate frontend.

Request a call

I will call you on the next working day between 9:00 and 17:00.

You can also call me directly.

+420 605 181 728

Leave your phone number and send a callback request.

By sending, you agree to processing your data in order to handle your request.