Hacker DirectoryHacker Directory

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.

CORE · RED · BLUE · ARTIFACT · PRACTICE

1. Core · Mechanism

Read every scenario without motion

CORS allowed

  1. 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
  2. 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
  3. 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
  4. 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
  5. 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
  6. 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
  7. 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
  8. 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

  1. 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
  2. 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
  3. 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
  4. 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
  5. 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

  1. 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
  2. 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
  3. 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
  4. 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
  5. 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
  6. 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
  7. 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
  8. 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

  1. 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
  2. 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
  3. 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
  4. 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

  1. 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
  2. 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
  3. 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
  4. 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
  5. 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
  6. 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

  1. 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
  2. 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
  3. 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
  4. 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
  5. 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
  6. 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

  1. 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
  2. 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
  3. 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
  4. 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
  5. 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
  6. 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

  1. 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
  2. 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
  3. 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
  4. 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
  5. 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
  6. 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?

  1. The GET was sent; its response is not exposed to the script.
  2. The GET was not sent; no response was produced.
  3. 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
  1. The value difference changes the safelist evaluation.
  2. POST always requires preflight; the first record is wrong.
  3. 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