concept Frontend & browsers
CORS and the same-origin policy
CORS permits browser scripts to read qualifying cross-origin responses. With credentials mode include, an explicit matching origin and credentials permission are required; a wildcard origin is insufficient.
What it means
The same-origin policy restricts cross-origin script access; CORS provides a server-controlled way to permit selected response sharing. This page examines that browser-access boundary, not API authorization or DNS configuration.
In the scene, Caller Origin identifies the origin making the script request. Allowed Origin header represents the response's Access-Control-Allow-Origin value, with none meaning the header is absent. Server allows credentials? = yes represents Access-Control-Allow-Credentials: true. The result tells you whether those selected values pass the modeled response checks—not whether an entire network transaction succeeded.
For the ordinary HTTPS addresses in this example, an origin is identified by scheme, host and port, not by the URL path. Thus https://shop.example and https://api.example are different origins; changing only /cart to /orders on the same scheme, host and port does not change the origin. Other URL types can have opaque origins and are outside this fixture.
Try it
Simulation: from the baseline shown, change only Credentialed request? to yes. Read the updated result and its reason, then use Compare with baseline to compare the two outcomes. No request is sent.
Evaluate a simple CORS response
Change one condition and inspect the computed result, its cause, and the model boundary.
Credentialed means credentials mode include, even when no cookie is sent. Simplified CORS response access: no preflight algorithm, redirect rules or actual fetch.
The selected origin header matches this simplified request policy.
| Input | Supplied value |
|---|---|
| Caller Origin | https://app.example |
| Allowed Origin header | * |
| Credentialed request? | no |
| Server allows credentials? | no |
Synthetic local learning example. No account, real network, server, filesystem, credential, command or production change is accessed.
About this model
Credentialed means credentials mode include, even when no cookie is sent. Simplified CORS response access: no preflight algorithm, redirect rules or actual fetch.
These are bounded teaching rules. Actual behavior needs the linked subject specifications and independent observations. The examples are not live checks.
The baseline result is “Script may read under these response checks.” Its explanation is: “The selected origin header matches this simplified request policy.” Here, * is accepted because Credentialed request? is no.
Keep Caller Origin = https://app.example, Allowed Origin header = *, and Server allows credentials? = no.
Reset restores Caller Origin = https://app.example, Allowed Origin header = *, Credentialed request? = no, and Server allows credentials? = no. It removes input errors and clears the comparison. It preserves your independent choices to open or close FAQ answers and About this model.
How it works
The simplified response check first needs usable origin permission. Allowed Origin header = none represents an absent Access-Control-Allow-Origin header and fails the check. An explicit allowed origin must match Caller Origin; permission for credentials cannot substitute for that match.
A wildcard is a separate branch. With Credentialed request? = no, * passes this model's origin check without requiring a credential-allowance signal. With Credentialed request? = yes, the wildcard is unacceptable. Here, yes means fetch credentials mode include, even if no cookie is actually sent.
For an explicit matching origin with credentials mode include, the check then also requires Access-Control-Allow-Credentials: true. For example, Caller Origin = https://app.example and Allowed Origin header = https://app.example still produce Script response access blocked when Credentialed request? = yes and Server allows credentials? = no. The origin match passes, but credential permission is missing. That is a different failure from the wildcard contrast below.
These decisions concern script access to a response. They do not establish whether a request was transmitted or processed; preflight and other request rules are outside this model.
Worked example
This is a synthetic baseline, not a captured browser observation.
| Input | Baseline value |
|---|---|
| Caller Origin | https://app.example |
| Allowed Origin header | * |
| Credentialed request? | no |
| Server allows credentials? | no |
The result is Script may read under these response checks. The explanation is: “The selected origin header matches this simplified request policy.”
The intermediate condition is the noncredentialed wildcard branch: is acceptable here, so the absent credential permission does not block this response check. The result does not mean that literally equals https://app.example; it means the wildcard rule applies to this selected request mode.
What changes when the condition changes
Change only Credentialed request? from no to yes. Caller Origin remains https://app.example, Allowed Origin header remains *, and Server allows credentials? remains no.
The result becomes Script response access blocked. The explanation is: “Wildcard origin does not allow credentialed response access.”
The response-header selections have not changed, but the request now uses credentials mode include. That changes which origin permission is acceptable: the wildcard no longer qualifies. The result follows the request's credentials mode, not whether a cookie happened to be sent.
In practice
Start with read-only inspection of an existing browser trace for a site and request you are authorized to investigate. Identify the requesting page's origin, the exact target request, its credentials mode, the response headers, and any preflight exchange. Do not paste cookies, tokens, or other secrets into this example.
Look for evidence that connects the request's origin and credentials mode to its actual Access-Control-Allow-Origin and Access-Control-Allow-Credentials values. Distinguish a network failure from a response that arrived but was unavailable to script. If the trace does not establish those facts, stop at insufficient evidence rather than substituting the scene's defaults. The simulation cannot verify a real request for you.
STOP: Do not resend a state-changing request merely to investigate a CORS message; the server may already have processed it. Do not disable browser security or broaden allowed origins just to silence an error. Server-side authorization remains necessary regardless of the browser's sharing decision. Any proposed policy change needs a separately authorized, narrowly scoped plan and verification with both allowed and disallowed callers.
Limits and unknowns
This scene evaluates only simplified CORS response-access checks. It does not run the preflight algorithm, follow redirects, send requests, or inspect a real browser, server, account, or deployment. A passing result is not proof that an actual fetch will succeed or that server-side permissions are correct.
The controls use fixed choices. If an input is reported invalid, no calculated outcome applies until you correct it or use Reset. Missing evidence about a real request leaves that request's outcome unknown; the scene does not retrieve the evidence or provide a live diagnosis.
Without JavaScript, the initial example and these explanations remain readable, but the interactive controls do not operate.
What to carry forward
Treat CORS as a response-sharing decision, not a verdict on the whole request. Match the caller's origin and credentials mode to the response headers before drawing a conclusion. If those facts are missing, collect authorized evidence rather than loosening policy.
Frequently asked questions
Editorial questions, answered from the sources listed for this article.
Does a blocked CORS response prove the server never processed the request?
No. Some requests can reach the server before the browser denies script access to the response. A CORS error alone cannot establish whether an action occurred; use authorized server-side evidence to determine processing rather than assuming the request did nothing.
Can Access-Control-Allow-Origin: * allow credentialed script access?
No. For credentials mode include, adding Access-Control-Allow-Credentials: true does not make Access-Control-Allow-Origin: * valid. The allowed origin must also explicitly match the caller. These are two required conditions, not alternative ways to grant access.
Does mode: no-cors bypass the restriction for JavaScript?
No. A no-cors request can produce an opaque response that does not expose the ordinary response data to JavaScript. It is not a general read-access bypass, and this scene does not evaluate that request mode.
Does CORS replace server-side authorization?
No. The server must independently check whether the caller may perform the requested action on the relevant resource. Browser sharing rules are not an authorization system for arbitrary clients; passing CORS checks does not establish that those permission checks are correct.
Sources & model boundaries
Primary references used for this explanation. The interactive example is an educational model, not a live check.
- WHATWG Fetch Living Standard
3.3 CORS protocol; 3.3.5 credentials; 4.10 CORS check; 2.2.6 Responses: opaque filtered response; main fetch: no-cors response tainting. CORS controls browser exposure under a request/response protocol; An opaque filtered response does not expose its underlying status, headers or body to script; no-cors is not permission to read a cross-origin response.
Checked .
- MDN: Cross-Origin Resource Sharing
Credentialed requests and wildcard origin. A wildcard does not enable credentialed script access; server authorization remains separate
Checked .
- OWASP: authorization
Least privilege, deny by default and permission checks. Server-side authorization must be checked for the relevant action and resource
Checked .
- WHATWG HTML: origins
7.1.1 Origins: tuple origin and same origin. Ordinary HTTP(S) origin comparison uses scheme, host and port, not path; opaque origins are a distinct case. The shop.example/api.example contrast is synthetic.
Checked .