WEB / WEB-11.02
CORS, preflight and credentials
Atlas’s browser requests a read-only list from Catalog API. Separate the OPTIONS check, actual GET and final response exposure decision.
1. Core · Mechanism
Read every scenario without motion
CORS allowed
- GET plus header
A normal read-only GET, X-Atlas-View header and include mode are selected; a cache miss requires preflight.
- Atlas · browser
- GET/header/include; preflight needed
- Catalog API
- Public catalog ready; no receipt
- OPTIONS arrived
The credential-free preflight arrived at the API; actual GET and script exposure have not occurred.
- Atlas · browser
- GET/header/include; preflight needed
- Catalog API
- OPTIONS received; no Cookie; policy pending
- Sharing policy
The API prepared a preflight response under selected origin, credentials and header policy; this is not user authorization.
- Atlas · browser
- GET/header/include; preflight needed
- Catalog API
- 204 response ready; header allowed
- Preflight receipt
The preflight response arrived at the browser; receipt is kept separate from local permission validation.
- Atlas · browser
- Preflight response received; gate pending
- Catalog API
- 204 response ready; header allowed
- Browser preflight gate
The browser checked original include mode and unsafe-header permission; actual GET sending is permitted.
- Atlas · browser
- Preflight passed; GET ready
- Catalog API
- 204 response ready; header allowed
- Actual GET arrived
The normal read-only GET arrived at the API; the selected public catalog response is ready and the final browser gate has not run.
- Atlas · browser
- Preflight passed; GET ready
- Catalog API
- GET received; read-only response ready
- Final response arrived
The actual GET response arrived at the browser; exact origin plus true ACAC is selected and script exposure is still pending.
- Atlas · browser
- Final response received; CORS pending
- Catalog API
- GET received; read-only response ready
- Final CORS gate
The browser final CORS check returned allow; the read-only GET already received by the server is not undone and no body parse is drawn.
- Atlas · browser
- Script exposure ready; body unread
- Catalog API
- GET received; read-only response ready
Preflight denied
- GET plus header
A normal read-only GET, X-Atlas-View header and include mode are selected; a cache miss requires preflight.
- Atlas · browser
- GET/header/include; preflight needed
- Catalog API
- Public catalog ready; no receipt
- OPTIONS arrived
The credential-free preflight arrived at the API; actual GET and script exposure have not occurred.
- Atlas · browser
- GET/header/include; preflight needed
- Catalog API
- OPTIONS received; no Cookie; policy pending
- Sharing policy
The API prepared a preflight response under selected origin, credentials and header policy; this is not user authorization.
- Atlas · browser
- GET/header/include; preflight needed
- Catalog API
- 204 response ready; header not allowed
- Preflight receipt
The preflight response arrived at the browser; receipt is kept separate from local permission validation.
- Atlas · browser
- Preflight response received; gate pending
- Catalog API
- 204 response ready; header not allowed
- Browser preflight gate
The browser checked original include mode and unsafe-header permission; no actual GET is sent.
- Atlas · browser
- Preflight denied; no GET; no exposure
- Catalog API
- 204 response ready; header not allowed
Final denied
- GET plus header
A normal read-only GET, X-Atlas-View header and include mode are selected; a cache miss requires preflight.
- Atlas · browser
- GET/header/include; preflight needed
- Catalog API
- Public catalog ready; no receipt
- OPTIONS arrived
The credential-free preflight arrived at the API; actual GET and script exposure have not occurred.
- Atlas · browser
- GET/header/include; preflight needed
- Catalog API
- OPTIONS received; no Cookie; policy pending
- Sharing policy
The API prepared a preflight response under selected origin, credentials and header policy; this is not user authorization.
- Atlas · browser
- GET/header/include; preflight needed
- Catalog API
- 204 response ready; header allowed
- Preflight receipt
The preflight response arrived at the browser; receipt is kept separate from local permission validation.
- Atlas · browser
- Preflight response received; gate pending
- Catalog API
- 204 response ready; header allowed
- Browser preflight gate
The browser checked original include mode and unsafe-header permission; actual GET sending is permitted.
- Atlas · browser
- Preflight passed; GET ready
- Catalog API
- 204 response ready; header allowed
- Actual GET arrived
The normal read-only GET arrived at the API; the selected public catalog response is ready and the final browser gate has not run.
- Atlas · browser
- Preflight passed; GET ready
- Catalog API
- GET received; read-only response ready
- Final response arrived
The actual GET response arrived at the browser; wildcard ACAO plus include mode is selected and script exposure is still pending.
- Atlas · browser
- Final response received; CORS pending
- Catalog API
- GET received; read-only response ready
- Final CORS gate
GET reached Catalog API and its final response reached the browser. With credentials mode include, ACAO * denies script exposure; ACAC true cannot repair that mismatch. Denial does not undo GET, and neither body reading nor DOM updates occurred.
- Atlas · browser
- Script exposure denied; GET was sent
- Catalog API
- GET received; read-only response ready
Plain GET
- Safelisted GET
The selected read-only GET has no author headers and uses omit mode; no other preflight flags are selected.
- Atlas · browser
- GET/omit; no author header
- Catalog API
- Public catalog ready; no receipt
- GET receipt
The normal GET requiring no preflight arrived at the API; the selected public-read response is ready.
- Atlas · browser
- GET/omit; no author header
- Catalog API
- GET received; wildcard response ready
- Response receipt
The response with wildcard ACAO arrived at the browser; the final CORS check under omit mode remains a separate step.
- Atlas · browser
- Response received; CORS pending
- Catalog API
- GET received; wildcard response ready
- Exposure ready
The wildcard passed the final check under omit; this is only script exposure, not DOM rendering or server-action permission.
- Atlas · browser
- Script exposure ready; body unread
- Catalog API
- GET received; wildcard response ready
ACTORS · STATE · DATA FLOW
To which script does the server expose a response?
CORS lets a server communicate response-sharing permission to the browser for scripts at particular origins through HTTP. It is not the API authorization system deciding which user can perform which operation. Atlas at https://atlas.example.org requests a normal fetch for https://catalog.example.org/list. In cors mode the browser checks CORS before exposing the response to script. Access-Control-Allow-Origin can be one serialized origin or a wildcard under a suitable credentials mode; a comma-separated origin list does not authorize several origins this way. Passing CORS still leaves body reading and JSON parsing as separate stages.
The scene uses two actors: Atlas’s browser and Catalog API. Its normal branch needs preflight because the GET includes an ordinary presentation header, X-Atlas-View: compact. This custom lab name is not a standard header. The API serves the read-only catalog under a selected public-read policy; OPTIONS proves neither that business policy nor a user’s authority. A browser-local CORS gate follows final response receipt; exposure-ready does not claim DOM rendering or actual API bytes were read.
Preflight checks more than the method
The CORS-safelisted methods are GET, HEAD and POST, but GET alone does not remove preflight. Author-controlled request header names and values must also satisfy safelist conditions. X-Atlas-View is not a safelisted name. Content-Type can be safelisted only when its MIME essence is application/x-www-form-urlencoded, multipart/form-data or text/plain and value conditions pass; JSON is outside that set. Accept has unsafe-byte and 128-byte limits, language headers have character conditions and Range has a single-byte-range condition. Streaming uploads or an explicit preflight flag also matter by profile.
The browser sends OPTIONS for the cross-origin check; Access-Control-Request-Method names the future GET and Access-Control-Request-Headers lists unsafe header names. Preflight has same-origin credentials mode and therefore carries no cross-origin credentials; nevertheless, if the original request uses include, its response must allow that use too. In the selected cache-miss branch, actual GET is not sent before an ok-status response passes origin/credentials and required-header permissions. A preflight cache hit can avoid a new OPTIONS; that cache is not the HTTP response cache. MDN notes implementation departures from this standard rule for some enterprise TLS client-certificate scenarios; the fixture selects the normative profile rather than promising actual wire behavior in every browser.
include is not an order to send a Cookie
Fetch defaults to same-origin credentials; include permits eligible credentials for cross-origin use. Cookie existence, Domain/Path/Secure, SameSite and browser privacy policy independently affect sending. Selecting include creates neither an absent cookie nor one blocked by policy. Final CORS checks follow include mode, requiring exact ACAO and case-sensitive true ACAC; wildcard ACAO is rejected in that mode even if no Cookie actually traveled. With omit, a wildcard can allow the selected public response.
ACAM, ACAH and exposed-header wildcards do not act as broad permission in include mode. Authorization is also a non-wildcard request-header name; a generic wildcard does not imply its permission. Response-header exposure is a separate allowlist; Set-Cookie is not an ordinary script-exposed header. Vary: Origin describes cache variation when response policy varies by request origin and can be cached; it is not presented as universally required for every fixed/wildcard response. Vary does not make a private response safe for public caching.
2. Red · Trust & Impact
Read every scenario without motion
Preflight deny
- Method and author header were selected together
The read-only GET has X-Atlas-View compact under cors/include with a selected preflight-cache miss. GET alone does not imply no preflight; header names and values contribute to that requirement.
- Catalog request facts
- GET + X-Atlas-View / preflight needed
- Preflight/final policy
- Sharing gate pending
- Send/exposure boundary
- No exposure verdict
- OPTIONS credentials were separated from the actual request
Preflight has credentialsMode same-origin and crossOriginCredentialsSent false. OPTIONS asks permission for the original GET/header. Include usage needs separate response-policy permission; credential-free OPTIONS does not remove final include rules.
- Catalog request facts
- GET + X-Atlas-View / preflight needed
- Preflight/final policy
- Preflight OPTIONS / cross-origin credentials not sent
- Send/exposure boundary
- No exposure verdict
- Missing header permission stopped the actual GET
preflightHeaderAllowed and preflightAccepted are false, so actualGetSent is false and finalACAO not received. No actual GET receipt is invented for this branch; OPTIONS is a separate exchange.
- Catalog request facts
- GET + X-Atlas-View / preflight needed
- Preflight/final policy
- Preflight OPTIONS / cross-origin credentials not sent
- Send/exposure boundary
- Preflight denied / actual GET not sent
- Plain GET provided an ordinary contrast
plain-get has safelisted input, preflightNeeded false and credentials omit. Wildcard ACAO allows scriptExposed true. The same GET method can follow different gates under different header/credential contexts.
- Catalog request facts
- Plain omit GET / no preflight / exposed
- Preflight/final policy
- Preflight OPTIONS / cross-origin credentials not sent
- Send/exposure boundary
- Preflight denied / actual GET not sent
- Safelist requirements retained narrow-fixture scope
The artifact distinguishes ordinary Accept examples of 128 and 129 bytes. Method, name and value matter together. This bounded ASCII matrix is not a complete Fetch-safelist/MIME parser or a general result for arbitrary headers.
- Catalog request facts
- Plain omit GET / no preflight / exposed
- Preflight/final policy
- Method/name/value scope retained
- Send/exposure boundary
- Preflight denied / actual GET not sent
- The send gate was not server authorization
Preflight success or absence grants no user/object authority. ServerActionPolicy is independently selected public-read without mutation. CORS failure does not prove CSRF protection or rejection of every request at the server.
- Catalog request facts
- Plain omit GET / no preflight / exposed
- Preflight/final policy
- Method/name/value scope retained
- Send/exposure boundary
- Send policy scoped / server authz independent
Final exposure
- Accepted preflight was separated from the final gate
final-blocked has preflightHeaderAllowed and preflightAccepted true with actualGetSent true. It represents an ordinary read-only flow where GET is sent. The final response gate evaluates another predicate.
- Catalog request facts
- Preflight accepted / GET sent
- Preflight/final policy
- Sharing gate pending
- Send/exposure boundary
- No exposure verdict
- Include mode was not exposed through a wildcard
Final ACAO is *, ACAC true and credentialsMode include, yielding scriptExposed false. Even if no cookie was actually sent, include-mode wildcard restrictions remain; mode and cookie bytes are separate predicates.
- Catalog request facts
- Preflight accepted / GET sent
- Preflight/final policy
- Include + ACAO* → exposure false
- Send/exposure boundary
- No exposure verdict
- Exposure denial did not undo server receipt
Actual GET sent remains true while script cannot read the body. A final CORS error does not mean the server never saw the request. Mutating actions need server-side policy; this fixture is public read-only GET.
- Catalog request facts
- Preflight accepted / GET sent
- Preflight/final policy
- Include + ACAO* → exposure false
- Send/exposure boundary
- GET sent / script withheld / server policy separate
- The exact-origin positive control gave another result
Normal finalACAO https://atlas.example.org with finalACAC true exposes the response under include mode. A trailing slash changes the serialized-origin value. ACAC True is not treated as lowercase true.
- Catalog request facts
- Exact origin + ACAC true → exposure true
- Preflight/final policy
- Include + ACAO* → exposure false
- Send/exposure boundary
- GET sent / script withheld / server policy separate
- Sharing policy did not make private data public
Vary Origin describes variation for dynamic-Origin responses; privateDataMadePublicByVary is false. CORS sharing replaces neither response classification nor object permission. Preflight caches and HTTP-response caches have distinct scopes.
- Catalog request facts
- Exact origin + ACAC true → exposure true
- Preflight/final policy
- Sharing/Vary scope / private policy separate
- Send/exposure boundary
- GET sent / script withheld / server policy separate
- Control retained the final-response contract
Approved serialized origin and exact lowercase true come from explicit configuration. The model runs no actual browser, network or cookie storage. Correct exposure does not remove independent validation of session/resource authority.
- Catalog request facts
- Exact origin + ACAC true → exposure true
- Preflight/final policy
- Sharing/Vary scope / private policy separate
- Send/exposure boundary
- Final sharing checked / current authority separate
ASSUMPTION · BOUNDARY · CONTROL
Which denial stops the request?
In preflight-denied, normal OPTIONS reaches the server but the browser sends no actual GET because X-Atlas-View permission is missing. In final-blocked, preflight passes and the read-only GET reaches the server; final response exposure is denied because a wildcard is used with include mode. The two denials have different network outcomes. A final CORS error does not undo the server’s GET receipt; the example has no mutation but shows why server-side action permissions need protection beyond CORS.
A diagnostic saying “GET needs no preflight” loses header-name/value conditions. The artifact compares ordinary 128-byte and 129-byte Accept values using the same method; the value boundary changes the result. Fetch also bounds aggregate safelisted value size; the local checker covers only the explicitly listed narrow value set. Method, headers and body describe a legal API request format, not automatic CORS permission or user authorization.
What changes when sharing expands?
A wider origin allowlist can widen the script-readable data boundary; assess that effect using response sensitivity and credential context. CORS success does not prove a session owner may read every object, and failure does not prove CSRF protection. Combining credential sending and script exposure into one boolean is especially misleading. This lesson uses only ordinary read-only fixtures for owned synthetic endpoints, without header manipulation, third-target or bypass flows.
3. Blue · Secure development & defense
Read every scenario without motion
Matrix review
- Four outcomes retained send and exposure fields
Catalog API owns preflight/final-response predicates; the Atlas browser owns exposure decisions after receiving them. cases/headerCases/exposureCases are authored policy records, not real access logs. preflight-denied reaches only OPTIONS; final-blocked also reaches GET. Omitted body/JSON/DOM stages cannot be inferred from script exposure. Normal is sent/exposed true, preflight deny false/false, final blocked true/false and plain omit GET true/true. One CORS-success boolean hides these different network and script outcomes.
- CORS observations
- Allow T/T / preflight F/F / final T/F / plain T/T
- Eligibility/exposure review
- Sharing gate pending
- Evidence verdict
- No exposure verdict
- Cookie eligibility required conditions beyond mode
Include mode does not automatically send a cookie; exists, scopeAndSecure and sameSiteAndPrivacy are required. Cross-origin same-origin and omit rows expect no sending. These declared predicates are compared without actual cookie bytes.
- CORS observations
- Allow T/T / preflight F/F / final T/F / plain T/T
- Eligibility/exposure review
- Include + existence/scope/privacy required
- Evidence verdict
- No exposure verdict
- The no-cookie row retained final include rules
The exposure matrix expects false for include/ACAO*/ACAC true/cookieSent false. Absence of sent credentials and request credentialsMode are different facts. Cookie-gate results cannot replace final sharing checks.
- CORS observations
- No cookie does not relax include wildcard rule
- Eligibility/exposure review
- Include + existence/scope/privacy required
- Evidence verdict
- No exposure verdict
- Origin and ACAC were checked with exact values
Omit mode may allow a wildcard; include needs exact origin and lowercase true. ACAC True and an origin with a trailing slash are false controls. Exact values explain sharing outcomes within the proper scope.
- CORS observations
- No cookie does not relax include wildcard rule
- Eligibility/exposure review
- Exact origin and lowercase true checked
- Evidence verdict
- No exposure verdict
- Cache inventories retained distinct contracts
HTTP responses varied by Origin and partitioned preflight caches are not one store. CacheProfile has timers false and preflightCacheDistinct true. Without observed expiration or cache hits, no max-age timing claim is added.
- CORS observations
- No cookie does not relax include wildcard rule
- Eligibility/exposure review
- Exact origin and lowercase true checked
- Evidence verdict
- HTTP variation ≠ preflight cache / timers unmeasured
- Matrix results were not native Fetch proof
This narrow ASCII/policy fixture uses ordinary read-only inputs. Redirects, browser-specific differences, cookie storage and response-body DOM behavior are outside scope. Correct typed predicates still need separate actual-browser enforcement evidence.
- CORS observations
- No cookie does not relax include wildcard rule
- Eligibility/exposure review
- Exact origin and lowercase true checked
- Evidence verdict
- Finite policy known / Fetch-browser runtime unmeasured
Phase gap
- The final error label was reviewed for its phase
Catalog API owns preflight/final-response predicates; the Atlas browser owns exposure decisions after receiving them. cases/headerCases/exposureCases are authored policy records, not real access logs. preflight-denied reaches only OPTIONS; final-blocked also reaches GET. Omitted body/JSON/DOM stages cannot be inferred from script exposure. The alternative review sees only a CORS-error label without preflight or actual-GET observations. It could mean preflight denial or final-exposure denial. The normal matrix’s different sending outcomes explain this ambiguity.
- CORS observations
- Error label only / phase unobserved
- Eligibility/exposure review
- Sharing gate pending
- Evidence verdict
- No exposure verdict
- A final error did not decide actual-request receipt
preflight-denied has actualGetSent false; final-blocked true. Missing phase records do not justify guessing either. Client-readable exposure and server receipt come from different observers.
- CORS observations
- Error label only / phase unobserved
- Eligibility/exposure review
- Error alone cannot determine GET sent
- Evidence verdict
- No exposure verdict
- A normal row did not replace missing observations
Normal preflight 204 with exact-origin final response is the expected flow. These values are not copied as response fields into an incomplete trace. Cache-hit possibilities are not inferred from the selected cache-miss fixture.
- CORS observations
- Expected normal flow is not missing-phase evidence
- Eligibility/exposure review
- Error alone cannot determine GET sent
- Evidence verdict
- No exposure verdict
- Required evidence was split into sending and exposure
Preflight outcome and actual-request receipt answer sending questions; final ACAO/ACAC/mode and browser exposure answer reading questions. Headers visible in Network do not independently prove script-API header readability.
- CORS observations
- Expected normal flow is not missing-phase evidence
- Eligibility/exposure review
- Need phase/result/receipt plus final exposure fields
- Evidence verdict
- No exposure verdict
- Sending and server-action verdicts remained unknown
Actual GET sending remains UNKNOWN for this review. There is no evidence of user/action authorization or mutation. Treating a CORS error as successful CSRF control or a server no-op exceeds scope.
- CORS observations
- Expected normal flow is not missing-phase evidence
- Eligibility/exposure review
- Need phase/result/receipt plus final exposure fields
- Evidence verdict
- UNKNOWN: actual GET sending / server action
- New evidence was bounded to minimal phase correlation
Further review needs scoped request origin, method/header names, preflight outcome and final-exposure records, not cookie/token bytes or full private bodies. Server-policy questions require independent evidence.
- CORS observations
- Expected normal flow is not missing-phase evidence
- Eligibility/exposure review
- Need phase/result/receipt plus final exposure fields
- Evidence verdict
- Collect scoped phase evidence; server policy separately
IMPLEMENTATION · SECURITY CONTROL · VERIFICATION
Operate sharing policy separately from API policy
Catalog API owns preflight/final-response predicates; the Atlas browser owns exposure decisions after receiving them. cases/headerCases/exposureCases are authored policy records, not real access logs. preflight-denied reaches only OPTIONS; final-blocked also reaches GET. Omitted body/JSON/DOM stages cannot be inferred from script exposure. Atlas selects a permitted serialized origin from configuration; in include mode ACAO is exact and ACAC is true. The OPTIONS route handles the browser’s credential-free check, while the actual resource route independently enforces user/session and object rules. The public catalog example selects public-read policy and has no state-changing action. An error response can also be exposed through suitable CORS headers; HTTP status is not identical to a successful business outcome. Preflight, however, requires an ok status.
Regression separates normal allowance, missing-header preflight denial, final wildcard/include denial and an omit GET without preflight. A header/value matrix explains preflight requirements, while cookieEligibility illustrates sending conditions; include-with-no-cookie still preserves the final CORS wildcard restriction. Final response received and response exposed are distinct states. Local step order shows when the supplied policy decision becomes available; actual Fetch execution or Cookie sending needs separate observation.
Two distinct cache policies
For caches, record both HTTP response variation by Origin and the browser preflight cache’s origin/URL/credentials/method/header scope. Max-Age can be limited by browser caps; the fixture runs no actual cache timer. Script access to response headers requires exposure policy; seeing them in browser devtools does not prove script API access. Actual networking, privacy settings, streaming uploads and endpoint authorization need separate isolated integration evidence.
NOW APPLY IT TO THE CASE
Why are preflight, final exposure and credential eligibility separate gates?
Atlas’s public catalog GET with X-Atlas-View needs preflight. Without header permission, actual GET is not sent. After accepted preflight, an include-mode wildcard final response leaves GET sent but denies script exposure. Include alone does not guarantee cookie transmission.
Which relationship does the case’s browser policy control? Explain exposure, destination or framing decisions separately from server object permission.
Open the related case file ↗READ THE EXAMPLE TOGETHER
Catalog sharing and send gate table
Select a field and examine what it supports and where the evidence ends.
Read the raw artifact and field explanations
{
"profile": {
"requestOrigin": "https://atlas.example.org",
"url": "https://catalog.example.org/list",
"mode": "cors",
"method": "GET",
"authorHeader": {
"name": "X-Atlas-View",
"value": "compact"
},
"preflightCache": "selected miss",
"credentials": "include",
"readOnly": true,
"serverActionPolicy": "selected public-read, independent of CORS",
"actualBrowser": false,
"actualNetwork": false,
"actualCookieBytes": false
},
"headerCases": [
{
"method": "GET",
"headers": [],
"expectedPreflight": false
},
{
"method": "GET",
"headers": [
{
"name": "X-Atlas-View",
"value": "compact"
}
],
"expectedPreflight": true
},
{
"method": "POST",
"headers": [
{
"name": "Content-Type",
"value": "text/plain;charset=UTF-8"
}
],
"expectedPreflight": false
},
{
"method": "POST",
"headers": [
{
"name": "Content-Type",
"value": "application/json"
}
],
"expectedPreflight": true
},
{
"method": "GET",
"headers": [
{
"name": "Accept",
"value": "text/plain;atlas=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
}
],
"expectedPreflight": false
},
{
"method": "GET",
"headers": [
{
"name": "Accept",
"value": "text/plain;atlas=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
}
],
"expectedPreflight": true
}
],
"preflight": {
"method": "OPTIONS",
"credentialsMode": "same-origin",
"crossOriginCredentialsSent": false,
"requestMethod": "GET",
"requestHeaderNames": [
"x-atlas-view"
],
"responseStatus": 204,
"ACAO": "https://atlas.example.org",
"ACAC": "true",
"ACAM": [
"GET"
],
"ACAH": [
"X-Atlas-View"
],
"normativeFetchProfile": true
},
"cases": [
{
"case": "normal",
"preflightNeeded": true,
"preflightHeaderAllowed": true,
"preflightAccepted": true,
"credentialsMode": "include",
"finalACAO": "https://atlas.example.org",
"finalACAC": "true",
"actualGetSent": true,
"scriptExposed": true
},
{
"case": "preflight-denied",
"preflightNeeded": true,
"preflightHeaderAllowed": false,
"preflightAccepted": false,
"credentialsMode": "include",
"finalACAO": "not received",
"finalACAC": "not received",
"actualGetSent": false,
"scriptExposed": false
},
{
"case": "final-blocked",
"preflightNeeded": true,
"preflightHeaderAllowed": true,
"preflightAccepted": true,
"credentialsMode": "include",
"finalACAO": "*",
"finalACAC": "true",
"actualGetSent": true,
"scriptExposed": false
},
{
"case": "plain-get",
"preflightNeeded": false,
"preflightHeaderAllowed": "not needed",
"preflightAccepted": "not needed",
"credentialsMode": "omit",
"finalACAO": "*",
"finalACAC": null,
"actualGetSent": true,
"scriptExposed": true
}
],
"exposureCases": [
{
"mode": "omit",
"ACAO": "*",
"ACAC": null,
"expected": true
},
{
"mode": "include",
"ACAO": "*",
"ACAC": "true",
"cookieSent": false,
"expected": false
},
{
"mode": "include",
"ACAO": "https://atlas.example.org",
"ACAC": "true",
"expected": true
},
{
"mode": "include",
"ACAO": "https://atlas.example.org",
"ACAC": "True",
"expected": false
},
{
"mode": "omit",
"ACAO": "https://atlas.example.org/",
"ACAC": null,
"expected": false
}
],
"cookieEligibility": [
{
"mode": "include",
"exists": true,
"scopeAndSecure": true,
"sameSiteAndPrivacy": true,
"expectedSent": true
},
{
"mode": "include",
"exists": true,
"scopeAndSecure": true,
"sameSiteAndPrivacy": false,
"expectedSent": false
},
{
"mode": "include",
"exists": false,
"scopeAndSecure": true,
"sameSiteAndPrivacy": true,
"expectedSent": false
},
{
"mode": "same-origin",
"exists": true,
"scopeAndSecure": true,
"sameSiteAndPrivacy": true,
"expectedSent": false
},
{
"mode": "omit",
"exists": true,
"scopeAndSecure": true,
"sameSiteAndPrivacy": true,
"expectedSent": false
}
],
"cacheProfile": {
"dynamicOriginResponse": true,
"Vary": [
"Origin"
],
"privateDataMadePublicByVary": false,
"preflightCacheDistinct": true,
"actualTimers": false,
"partitionKeyScope": "network partition key plus request origin/URL/credentials/method/header"
},
"omitted": [
"redirects",
"browser-specific preflight/credential differences",
"streaming uploads and explicit preflight flag",
"full MIME/range/header safelist parser",
"HTTP and preflight cache execution",
"cookie storage/Set-Cookie",
"response body/JSON/DOM"
]
}- headerCases
- Method and header name/value together; narrow ASCII examples.
- preflight
- Credential-free OPTIONS; response must separately allow original include usage.
- cases
- Actual GET sending and final script exposure are separate outcomes.
- exposureCases
- Exact origin and byte-case-sensitive true checks.
- cookieEligibility
- Mode differs from cookie policy; no real cookie is sent.
- cacheProfile
- Selected dynamic HTTP variation and a separate preflight cache.
A narrow ordinary read-only CORS policy fixture, not a general Fetch/MIME/header parser or browser emulator. Credential conditions are declared; no token/cookie bytes or network.
Two reality checks
Every GET fetch avoids preflight.
Author-header name/value and other Fetch conditions matter; a custom presentation header can require a GET preflight.
CORS denial proves the server never processed the request.
Preflight denial can stop the actual request; final exposure denial does not undo a request already received.
YOUR TURN
Work through this story.
Predict the outcome, find the evidence boundary, and explain it in your own words.
Preflight for the catalog GET was accepted. The final response has ACAO: * and ACAC: true; credentials mode is include. Which pair of outcomes is expected?
- The GET was sent; its response is not exposed to the script.
- The GET was not sent; no response was produced.
- The script can read the GET response because ACAC is true.
Read the explained answer
The GET was sent; its response is not exposed to the script. — The fixture fields actualGetSent=true and scriptExposed=false represent two distinct boundaries. A CORS exposure block is not authorization or a rollback mechanism for server processing.
These two Content-Type records use the same POST method. Why do their preflight expectations differ?
Selected narrow header fixture; not a browser capture
- POST / Content-Type #1
- text/plain;charset=UTF-8 → expectedPreflight=false
- POST / Content-Type #2
- application/json → expectedPreflight=true
- profile
- selected ASCII values; other safelist conditions satisfied
- The value difference changes the safelist evaluation.
- POST always requires preflight; the first record is wrong.
- The second record’s preflight proves the user is authorized.
Read the explained answer
The value difference changes the safelist evaluation. — This finite example teaches only the distinction between two values under the stated conditions. It is not a general MIME/header parser or an actual browser execution claim.
Include mode is selected but no eligible Cookie exists. Does this make wildcard ACAO valid for the include-mode response? Also distinguish CORS from application permission.
Read the explained answer
No. The selected CORS check uses credentials mode; sending no Cookie in this request does not turn include into omit. Cookie sending depends on existence, scope/Secure and SameSite/privacy conditions. CORS limits which script can read a response; the server must separately enforce resource/action permission.
□ I did not equate include mode with sending Cookie bytes.
□ I explained the wildcard limitation using the mode.
□ I distinguished script exposure from server authorization.
Open the application console · request / response / browser
Also open request, URL, cookie and DOM examples
Sources and scope
- WHATWG Fetch — CORS protocol and algorithms§2.2.1 CORS-safelisted method; §2.2.2 CORS-safelisted request-header · §3.3.2 HTTP requests; §3.3.3 HTTP responses · §3.3.5 CORS protocol and credentials · §4.8 CORS-preflight fetch; §4.9 CORS-preflight cache; §4.10 CORS check · §2.2.2 forbidden response-header; §3.1 Cookie infrastructure
- MDN — Cross-Origin Resource Sharing (CORS)Simple requests; Preflighted requests · Requests with credentials; Preflight requests and credentials · Access-Control-Allow-Origin and Vary: Origin · Access-Control-Expose-Headers
- MDN — Same-origin policyDefinition of an origin; Inherited origins; File origins · Cross-origin network access: writes, embeds, reads · Cross-origin script API access: Window and Location · Cross-origin data storage access