Skip to content
>_ITDITDWeb Security Platform

Glossary

What is CORS — how it works, and what a misconfiguration exposes

CORS controls whether one site's JavaScript can read another origin's API responses. A too-permissive 'CORS misconfiguration' can let a third-party site read a logged-in user's data. How it works and safe settings (allowlist, don't reflect Origin, never combine * with credentials), explained defensively.

Published 2026-06-11 Updated 2026-06-11 3 min read

"I added Access-Control-Allow-Origin and the API worked — is this safe?" CORS isn't "add it and you're done"; the point is narrowing who you allow. Here's how it works and how to set it safely (no attack steps).

First, how it works

Browsers enforce a same-origin policy: JS from another origin can't freely read another site's responses. CORS exists to open that exception only to parties the server explicitly allows.

Response headerMeaning
Access-Control-Allow-OriginWhich origins may read the response
Access-Control-Allow-CredentialsWhether requests with credentials (cookies) are allowed
Access-Control-Allow-Methods / -HeadersWhich HTTP methods/headers are allowed

The point: CORS is on the "loosen the restriction" side. Loosen it wrong and data that shouldn't be readable becomes readable to third parties.

What makes a setting dangerous

Dangerous settings (common)

  • Reflecting the request's Origin back as allowed
  • Access-Control-Allow-Origin: * plus allowing credentials
  • Opening APIs broadly cross-origin that don't need it

Safe settings

  • An allowlist (only fixed, trusted origins)
  • Default deny for everything else
  • For credentialed requests, a specific origin, not *
An attacker site's JS requests your API (the user is logged in)
↓ the server blindly allows the Origin (misconfiguration)
the browser permits reading the response = personal data/tokens reach the attacker site
With a loose setting, an attacker site's JS can use the user's logged-in state to read the API response.

The basics of a safe setting

1

Use an allowlist (most important)

Permit only pre-decided trusted origins and deny the rest (default deny). Don't "just allow everything."
2

Don't blindly reflect Origin

Don't echo the request's Origin straight into Access-Control-Allow-Origin. Return it only when it matches the allowlist.
3

Never use * with credentials

Don't combine Access-Control-Allow-Origin: * with Allow-Credentials: true. Name a specific origin instead.
4

Minimize what you open

Only the endpoints that genuinely need to be cross-origin. Don't open broadly. Check your settings with the security headers checker.

This site's view: CORS is 'how you loosen,' not 'defense' — narrow who you open to

A common misconception is "adding CORS headers makes it safe." It's the opposite — CORS loosens the browser's restriction. So the trick isn't "how you add it" but "minimizing who, and how far, you open to." On this site we separate data that's fine to read externally from data that isn't, and recommend default deny, with an allowlist opening only the exceptions. Note that XSS (which breaks the read assumption) and CSRF (which targets state changes) are separate bugs — CORS alone doesn't cover everything.

FAQ

QWhat is CORS for?
A

Browsers enforce a same-origin policy: JavaScript from one origin (site) can't freely read another site's responses. CORS (Cross-Origin Resource Sharing) is how a server opens that exception — but only to parties it explicitly allows. Response headers like Access-Control-Allow-Origin declare which origins may read the response.

QWhat does a CORS misconfiguration expose?
A

Too-loose permissions can let an attacker's site read a user's logged-in API responses via JavaScript. Classic cases: reflecting the request's Origin back as allowed, or setting Access-Control-Allow-Origin to * while also allowing credentials (cookies). The result is that personal data or tokens can reach a third-party site.

QWhat's the basis of a safe setting?
A

An allowlist. Permit only pre-decided trusted origins and deny the rest (default deny). Don't blindly reflect the request's Origin. For credentialed requests, don't use * for Access-Control-Allow-Origin — name a specific origin. And only expose the endpoints that genuinely need to be cross-origin.