Hacker DirectoryHacker Directory

WEB / WEB-11.S01

CSRF, ambient credentials and action intent

Why is an authenticated request insufficient evidence of intent or object permission?

CORE · RED · BLUE · ARTIFACT · PRACTICE

1. Core · Mechanism

Read every scenario without motion

Intended action

  1. UI selection

    Duru wants reading-view-A to change from list to cards. Session, bound token and exact Atlas origin are supplied inputs; no POST has yet been prepared and the server record remains list. No actual cookie or action executes.

    Browser UI
    View=list; action pending
    Atlas action gate
    Record=list; no request
  2. Request prepared

    Session/token are declared validation aliases; a fixed POST envelope is prepared as data.

    Browser UI
    Save-view request ready
    Atlas action gate
    Record=list; no request
  3. Request arrived at gate

    The prepared ordinary request arrives; credentials do not establish intent approval.

    Browser UI
    Save-view request ready
    Atlas action gate
    Request arrived; record=list
  4. Local provenance gate

    Token/session binding, exact source origin and metadata policy are evaluated separately and locally.

    Browser UI
    Save-view request ready
    Atlas action gate
    Provenance accepted; record=list
  5. Local action permission

    Even valid provenance needs tenant/object/action permission; only an accepted row changes state.

    Browser UI
    Save-view request ready
    Atlas action gate
    Record=cards; accepted response ready
  6. Response at UI

    The selected accepted/denied action result reached the browser. The UI still shows list; response receipt is not equivalent to interpretation or action success.

    Browser UI
    Result arrived; view=list
    Atlas action gate
    Record=cards; accepted response ready
  7. Local UI outcome

    Provenance and the separate action permission passed, changing the reading-view record to cards. The UI interprets acceptance after response receipt; no real endpoint action was executed.

    Browser UI
    View=cards; confirmed
    Atlas action gate
    Record=cards; accepted response ready

Missing token

  1. UI selection

    Duru selects cards; the session is valid and the source origin is Atlas, but tokenPresent is false. The server has not received these inputs yet; list and action-pending state are retained.

    Browser UI
    View=list; action pending
    Atlas action gate
    Record=list; no request
  2. Request prepared

    Session/token are declared validation aliases; a fixed POST envelope is prepared as data.

    Browser UI
    Save-view request ready
    Atlas action gate
    Record=list; no request
  3. Request arrived at gate

    The prepared ordinary request arrives; credentials do not establish intent approval.

    Browser UI
    Save-view request ready
    Atlas action gate
    Request arrived; record=list
  4. Local provenance gate

    Token/session binding, exact source origin and metadata policy are evaluated separately and locally.

    Browser UI
    Save-view request ready
    Atlas action gate
    Provenance denied; record=list
  5. Local action permission

    Provenance denial prepares accepted=false; the reading-view record remains list and the action mutation is skipped. This branch does not establish a separate object-permission pass or denial.

    Browser UI
    Save-view request ready
    Atlas action gate
    Record=list; denied response ready
  6. Response at UI

    The selected accepted/denied action result reached the browser. The UI still shows list; response receipt is not equivalent to interpretation or action success.

    Browser UI
    Result arrived; view=list
    Atlas action gate
    Record=list; denied response ready
  7. Local UI outcome

    Missing token denied provenance; both record and UI remain list. This does not prove session invalidity or object-permission denial; the action mutation was not applied.

    Browser UI
    View=list; unchanged
    Atlas action gate
    Record=list; denied response ready

Sibling origin

  1. UI selection

    Duru selects cards with a bound token, but sourceOrigin notes.example.org differs from the Atlas target origin. Same-site metadata is not an exact-origin match; no server decision has occurred yet.

    Browser UI
    View=list; action pending
    Atlas action gate
    Record=list; no request
  2. Request prepared

    Session/token are declared validation aliases; a fixed POST envelope is prepared as data.

    Browser UI
    Save-view request ready
    Atlas action gate
    Record=list; no request
  3. Request arrived at gate

    The prepared ordinary request arrives; credentials do not establish intent approval.

    Browser UI
    Save-view request ready
    Atlas action gate
    Request arrived; record=list
  4. Local provenance gate

    Token/session binding, exact source origin and metadata policy are evaluated separately and locally.

    Browser UI
    Save-view request ready
    Atlas action gate
    Provenance denied; record=list
  5. Local action permission

    Provenance denial prepares accepted=false; the reading-view record remains list and the action mutation is skipped. This branch does not establish a separate object-permission pass or denial.

    Browser UI
    Save-view request ready
    Atlas action gate
    Record=list; denied response ready
  6. Response at UI

    The selected accepted/denied action result reached the browser. The UI still shows list; response receipt is not equivalent to interpretation or action success.

    Browser UI
    Result arrived; view=list
    Atlas action gate
    Record=list; denied response ready
  7. Local UI outcome

    Although notes.example.org is within the same site, it is not the exact Atlas origin; provenance was denied. Record and UI retain list and no action mutation was applied. Token binding does not remove the origin condition.

    Browser UI
    View=list; unchanged
    Atlas action gate
    Record=list; denied response ready

Permission denied

  1. UI selection

    Duru selects cards; session, bound token and exact-origin inputs are positive. The object is in tenant-B and actionAuthorized is false; the server makes that separate permission decision after request receipt.

    Browser UI
    View=list; action pending
    Atlas action gate
    Record=list; no request
  2. Request prepared

    Session/token are declared validation aliases; a fixed POST envelope is prepared as data.

    Browser UI
    Save-view request ready
    Atlas action gate
    Record=list; no request
  3. Request arrived at gate

    The prepared ordinary request arrives; credentials do not establish intent approval.

    Browser UI
    Save-view request ready
    Atlas action gate
    Request arrived; record=list
  4. Local provenance gate

    Token/session binding, exact source origin and metadata policy are evaluated separately and locally.

    Browser UI
    Save-view request ready
    Atlas action gate
    Provenance accepted; record=list
  5. Local action permission

    Even valid provenance needs tenant/object/action permission; only an accepted row changes state.

    Browser UI
    Save-view request ready
    Atlas action gate
    Record=list; denied response ready
  6. Response at UI

    The selected accepted/denied action result reached the browser. The UI still shows list; response receipt is not equivalent to interpretation or action success.

    Browser UI
    Result arrived; view=list
    Atlas action gate
    Record=list; denied response ready
  7. Local UI outcome

    Provenance passed, but the separate action decision denied actionAuthorized false for the tenant-B object. Record and UI remain list; do not classify this as token or Origin rejection.

    Browser UI
    View=list; unchanged
    Atlas action gate
    Record=list; denied response ready

ACTORS · STATE · DATA FLOW

Ambient identity does not establish action intent

Duru saves her Atlas reading view from list to cards. The browser may attach an eligible session cookie as an ambient credential, but carrying her identity does not establish that the request originated from her intended UI action. Eligibility depends on domain/path, scheme/Secure, SameSite, credentials mode and browser storage policy; not every cross-origin request carries cookies. HttpOnly restricts JavaScript reading a cookie, not its attachment to eligible requests. CSRF concerns how expected request provenance and action-intent binding are established for authenticated state changes. Server authentication and object/action authorization remain separate questions.

Tokens, Origin and metadata provide different evidence

The selected save-reading-view policy requires a session-bound synchronizer-token validation result. The ledger shows token-present/token-bound booleans, not real secrets. The server verifies the token’s relation to the authenticated session; a signed double-submit design needs session binding as well as a signature. Tokens stay out of URLs and logs. Exact Origin comparison includes scheme, host and port and describes browser source context; opaque null or missing origins do not prove same-origin. Trusted target origin comes from server configuration, not arbitrary forwarded data. Fetch Metadata describes same-origin/same-site/cross-site/none relationships and needs explicit fallback for invalid or unavailable fields. Atlas requires token plus exact origin, accepts that fallback when metadata is absent, and rejects known cross-site state changes.

Separate SameSite, origin and business actions

SameSite compares schemeful sites: notes.example.org and atlas.example.org over HTTPS may be different origins within one site. Strict or Lax does not automatically make a sibling origin a trusted actor. Explicit Lax can admit cross-site top-level safe navigation; that does not imply the same result for fetch or POST, and browser default-Lax grace differs from explicit Lax. None requires Secure while third-party policy still applies. Safe methods such as GET/HEAD should not change application state. After provenance passes, the server separately authorizes Duru’s object/tenant action. Sensitive actions may need explicit confirmation or reauthentication bound to the transaction; a header cannot mathematically prove a human’s intent.

2. Red · Trust & Impact

Read every scenario without motion

Token and origin

  1. Normal action intent

    The normal row has sessionValid, tokenPresent and tokenBound true with Atlas sourceOrigin. It requests cards for reading-view-A in tenant-A; the token is only a non-secret alias.

    Request decision ledger
    Normal session/token/origin/action accepted
    Provenance and authority
    Not yet evaluated
    Reading-view result
    Not yet evaluated
  2. Credential is insufficient

    token-missing retains a valid session and action permission but provenance is false. Browser credential transmission cannot replace trusted UI intent or session-bound validation.

    Request decision ledger
    Normal session/token/origin/action accepted
    Provenance and authority
    Valid session / missing token / provenance false
    Reading-view result
    Not yet evaluated
  3. Retain the state

    token-missing has expectedAccepted false and expectedAfter list. The model does not apply the action or derive cards success merely from a valid session.

    Request decision ledger
    Normal session/token/origin/action accepted
    Provenance and authority
    Valid session / missing token / provenance false
    Reading-view result
    Token missing / list retained
  4. Same-site origin difference

    sibling-origin uses notes.example.org and same-site metadata. Its bound token does not make it equal to exact Atlas origin; same-site classification is not trusted-origin approval.

    Request decision ledger
    Same-site sibling / exact origin false
    Provenance and authority
    Valid session / missing token / provenance false
    Reading-view result
    Token missing / list retained
  5. Narrow purpose of the policy

    Exact origin and bound token contribute to provenance. Metadata does not conclusively prove human intent, and CORS read denial does not prove no server request.

    Request decision ledger
    Same-site sibling / exact origin false
    Provenance and authority
    Provenance gate ≠ human intent proof
    Reading-view result
    Token missing / list retained
  6. Rejection scope

    Both provenance rejections retain list. No actual cookie, token or action executes here; the result is not reassigned to session invalidity or tenant denial.

    Request decision ledger
    Same-site sibling / exact origin false
    Provenance and authority
    Provenance gate ≠ human intent proof
    Reading-view result
    Missing-token/sibling-origin → unchanged list

Action permission

  1. Positive provenance

    permission-denied passes session, token and exact-origin checks. expectedProvenance is true; it is not token failure but a separate action/object decision.

    Request decision ledger
    Valid provenance / permission review pending
    Provenance and authority
    Not yet evaluated
    Reading-view result
    Not yet evaluated
  2. Tenant and action binding

    objectTenant is tenant-B, Duru belongs to tenant-A and actionAuthorized is false. Valid provenance does not authorize an operation on that object.

    Request decision ledger
    Valid provenance / permission review pending
    Provenance and authority
    tenant-B ≠ tenant-A / action false
    Reading-view result
    Not yet evaluated
  3. Same unchanged outcome

    expectedAfter is again list, but the reason differs from token-missing. Visible before/after or a generic status may not identify the rejecting gate.

    Request decision ledger
    Valid provenance / permission review pending
    Provenance and authority
    tenant-B ≠ tenant-A / action false
    Reading-view result
    Permission denied / list retained
  4. Cookie eligibility distinction

    The explicit SameSite table can allow a same-site POST under Lax but not a cross-site unsafe POST. Cookie inclusion is neither action authorization nor exact-origin approval.

    Request decision ledger
    Cookie inclusion ≠ action permission
    Provenance and authority
    tenant-B ≠ tenant-A / action false
    Reading-view result
    Permission denied / list retained
  5. Retain HttpOnly purpose

    HttpOnly does not stop browser transmission of an eligible cookie. Secure, SameSite, credentials and server action policy answer different questions; one flag does not provide all intent controls.

    Request decision ledger
    Cookie inclusion ≠ action permission
    Provenance and authority
    Separate cookie/provenance/object decisions
    Reading-view result
    Permission denied / list retained
  6. Keep impact bounded

    Normal reaches cards and rejections retain list. This bounded reading-view result is not expanded to whole-account or origin compromise; permission and intent remain separate.

    Request decision ledger
    Cookie inclusion ≠ action permission
    Provenance and authority
    Separate cookie/provenance/object decisions
    Reading-view result
    Bounded reading-view transition / no broad claim

ASSUMPTION · BOUNDARY · CONTROL

Accepting a state change merely because a session exists

A normal cookie-backed UI request carries browser state. The broken assumption is that credentials always carry trusted UI intent as well. Risk requires eligible ambient credentials, a relevant state-changing handler and insufficient provenance/intent controls; its scope is limited by the authenticated user’s available actions. CORS or SOP read denial does not prove the server received no request. Missing-token and sibling-origin rows here are inert policy rejections, not executed CSRF requests. Controls bind token validation to server-owned session context and evaluate provenance correctly; a UI checkbox or action name alone does not establish trust.

An origin or token result can be overinterpreted

A valid token and trusted origin can still refer to an object in another tenant. The permission-denied branch separates that failure and leaves the reading-view record unchanged. Same-site metadata covers different origins, and none does not imply arbitrary trusted business intent. Compatibility exceptions for missing headers must not silently remove controls; exceptional clients may need a separate authenticated channel/policy. Same-origin code deriving an action or endpoint from untrusted URL data can also lose intent binding; this lesson generates no arbitrary endpoint or code. Expired sessions, old tokens/back-button forms and proxy omissions deserve diagnosis without automatically labeling an attack. Potential impact is the relevant state change, not a blanket account or origin compromise.

3. Blue · Secure development & defense

Read every scenario without motion

Decision controls

  1. Normal baseline

    The rows table carries supplied validation and permission inputs for the server action gate; sameSite is a separate cookie-eligibility prediction. Cookie sending is not observed here. Every Core branch reaches request arrival: token-missing and sibling-origin stop at provenance, while permission-denied fails the separate action decision after provenance. A retained list cannot distinguish these reasons; gate reasons and a receipt correlated with that action are needed. Session, token presence/binding, origin and metadata are separate fields. The normal baseline has an owned tenant-A object and permitted action, yielding provenance/accepted true and cards.

    Decision fields
    Normal accepted / list → cards
    Correlation review
    Not yet evaluated
    State evidence
    Not yet evaluated
  2. Two different denial reasons

    token-missing and sibling-origin have false provenance; permission-denied has true provenance but false acceptance. Reason and action correlation distinguish the same unchanged list outcome.

    Decision fields
    Normal accepted / list → cards
    Correlation review
    Provenance deny ≠ object/action deny
    State evidence
    Not yet evaluated
  3. Comparison instead of secrets

    Raw token/cookie values are unnecessary; tokenPresent, tokenBound and rejection reason are bounded evidence. The non-secret validation alias is not converted into an actual token or runtime input.

    Decision fields
    Normal accepted / list → cards
    Correlation review
    Provenance deny ≠ object/action deny
    State evidence
    Comparison reasons / no raw token
  4. Metadata fallback

    Absent or invalid metadata uses the configured token/exact-origin fallback. Missing origin or the null origin string is rejected; unrecognized-value is absent-like while known cross-site stays denied.

    Decision fields
    Fallback scoped / null origin denied
    Correlation review
    Provenance deny ≠ object/action deny
    State evidence
    Comparison reasons / no raw token
  5. SameSite control boundary

    The Strict/Lax/None table assumes explicit attributes and eligible cookies. It models no default grace, redirects or browser privacy restrictions and proves no actual cookie transmission.

    Decision fields
    Fallback scoped / null origin denied
    Correlation review
    Explicit attributes / finite inclusion predicates
    State evidence
    Comparison reasons / no raw token
  6. UI after transition

    UI success is bound to an accepted state transition. Regression retains provenance-valid/action-denied separation; passing the matrix is not reported as executing a real endpoint action.

    Decision fields
    Fallback scoped / null origin denied
    Correlation review
    Explicit attributes / finite inclusion predicates
    State evidence
    Reason + accepted + after / runtime separate

Missing reason

  1. List-only result

    The rows table carries supplied validation and permission inputs for the server action gate; sameSite is a separate cookie-eligibility prediction. Cookie sending is not observed here. Every Core branch reaches request arrival: token-missing and sibling-origin stop at provenance, while permission-denied fails the separate action decision after provenance. A retained list cannot distinguish these reasons; gate reasons and a receipt correlated with that action are needed. The review sees only a retained list, without decision reason or receipt. token-missing, sibling-origin and permission-denied produce the same visible state.

    Decision fields
    List unchanged / gate reason missing
    Correlation review
    Not yet evaluated
    State evidence
    Not yet evaluated
  2. Do not infer gate from status

    A generic status or client error does not supply the reason. Writing tokenBound false without token evidence would invent a provenance decision for this event.

    Decision fields
    List unchanged / gate reason missing
    Correlation review
    Status ≠ provenance/object reason
    State evidence
    Not yet evaluated
  3. Scope the unknowns

    After list is known while session/provenance/action gate results remain UNKNOWN. The normal accepted row cannot replace server receipt or transition evidence for the incomplete event.

    Decision fields
    List unchanged / gate reason missing
    Correlation review
    Status ≠ provenance/object reason
    State evidence
    After list known / decision gates UNKNOWN
  4. Required decision record

    Session validity, token comparison, source verification, metadata fallback and object/action permission must be associated with the action. Reasons can be retained without raw tokens or private bodies.

    Decision fields
    Needed: action correlation and gate reasons
    Correlation review
    Status ≠ provenance/object reason
    State evidence
    After list known / decision gates UNKNOWN
  5. No-op versus denial

    If no request arrived, server denial cannot be claimed. Client cancellation or stale UI cannot substitute for an action ledger; each stage needs an observation point.

    Decision fields
    Needed: action correlation and gate reasons
    Correlation review
    Receipt required / no invented server denial
    State evidence
    After list known / decision gates UNKNOWN
  6. Outcome of new evidence

    New evidence must retain normal and distinct rejection controls. This record reports only unchanged list, adding neither token success nor object-denial reasons.

    Decision fields
    Needed: action correlation and gate reasons
    Correlation review
    Receipt required / no invented server denial
    State evidence
    Retain list / collect scoped decision evidence

IMPLEMENTATION · SECURITY CONTROL · VERIFICATION

Log decision reasons separately from identity

The rows table carries supplied validation and permission inputs for the server action gate; sameSite is a separate cookie-eligibility prediction. Cookie sending is not observed here. Every Core branch reaches request arrival: token-missing and sibling-origin stop at provenance, while permission-denied fails the separate action decision after provenance. A retained list cannot distinguish these reasons; gate reasons and a receipt correlated with that action are needed. Record session validity, token presence/validation/binding, origin match, metadata/fallback, ownership and action permission as separate server decision fields. Do not log raw tokens or cookies; validation results and rejection reasons suffice. The ordinary baseline is a trusted origin, valid token and owned object. Classify old sessions or absent metadata at their actual gates. Status alone may not distinguish token failure from object denial, so internal reasons and action correlation complete the observation. Show UI success only after an accepted server transition. The inert matrix records before=list and after=cards or unchanged; modeled responses do not claim execution of a real endpoint action.

Test compatibility and action semantics

Prefer maintained framework CSRF controls while matching session rotation, multiple tabs, back navigation and token lifetimes to the product flow. Atlas regression separates valid provenance with denied action and same-site with different origin. The SameSite table is scoped to explicit attributes and assumed credential eligibility. Test token plus source verification fallback for absent/invalid metadata and do not add null to a trusted origin list. Behind proxies, trusted configuration determines the target origin; approved cross-origin flows must not become a generic exemption. Read GET endpoints remain nonmutating and actions carry an explicit method/intent contract. Choose stronger confirmation for sensitive operations rather than imposing the same challenge on every request, and do not present CORS as the sole CSRF defense.

NOW APPLY IT TO THE CASE

Is an action automatically accepted when session and token are valid?

Duru wants to change reading-view-A in tenant-A from list to cards. The normal POST passes session, token binding, exact origin and action permission. A missing token, different same-site origin or tenant-B object retains the same before state; we will distinguish the rejecting gate.

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

Ambient credentials and action-intent matrix

Select a field and examine what it supports and where the evidence ends.

Read the raw artifact and field explanations
{
  "profile": {
    "targetOrigin": "https://atlas.example.org",
    "actor": "Duru",
    "tenant": "tenant-A",
    "action": "save-reading-view",
    "method": "POST",
    "record": "reading-view-A",
    "before": "list",
    "desired": "cards",
    "token": "session-bound-validation-alias",
    "tokenIsActualSecret": false,
    "actualRequest": false,
    "actualCookie": false,
    "actualAction": false
  },
  "rows": [
    {
      "case": "normal",
      "sessionValid": true,
      "tokenPresent": true,
      "tokenBound": true,
      "sourceOrigin": "https://atlas.example.org",
      "metadata": "same-origin",
      "actionAuthorized": true,
      "objectTenant": "tenant-A",
      "expectedProvenance": true,
      "expectedAccepted": true,
      "expectedAfter": "cards"
    },
    {
      "case": "token-missing",
      "sessionValid": true,
      "tokenPresent": false,
      "tokenBound": false,
      "sourceOrigin": "https://atlas.example.org",
      "metadata": "same-origin",
      "actionAuthorized": true,
      "objectTenant": "tenant-A",
      "expectedProvenance": false,
      "expectedAccepted": false,
      "expectedAfter": "list"
    },
    {
      "case": "sibling-origin",
      "sessionValid": true,
      "tokenPresent": true,
      "tokenBound": true,
      "sourceOrigin": "https://notes.example.org",
      "metadata": "same-site",
      "actionAuthorized": true,
      "objectTenant": "tenant-A",
      "expectedProvenance": false,
      "expectedAccepted": false,
      "expectedAfter": "list"
    },
    {
      "case": "permission-denied",
      "sessionValid": true,
      "tokenPresent": true,
      "tokenBound": true,
      "sourceOrigin": "https://atlas.example.org",
      "metadata": "same-origin",
      "actionAuthorized": false,
      "objectTenant": "tenant-B",
      "expectedProvenance": true,
      "expectedAccepted": false,
      "expectedAfter": "list"
    }
  ],
  "provenancePolicy": {
    "requireTokenPresentAndBound": true,
    "requireExactOrigin": true,
    "knownMetadataAllowed": [
      "same-origin"
    ],
    "absentMetadata": "token+exact-origin fallback",
    "invalidMetadata": "treat as absent then configured fallback",
    "nullOriginAllowed": false
  },
  "fallbackRows": [
    {
      "origin": "https://atlas.example.org",
      "tokenBound": true,
      "metadata": null,
      "expected": true
    },
    {
      "origin": null,
      "tokenBound": true,
      "metadata": null,
      "expected": false
    },
    {
      "origin": "null",
      "tokenBound": true,
      "metadata": null,
      "expected": false
    },
    {
      "origin": "https://atlas.example.org",
      "tokenBound": true,
      "metadata": "unrecognized-value",
      "expected": true
    },
    {
      "origin": "https://atlas.example.org",
      "tokenBound": true,
      "metadata": "cross-site",
      "expected": false
    }
  ],
  "sameSite": {
    "profile": "explicit attributes only; eligible host/path/unexpired cookie, HTTPS, no browser partition/storage restrictions, credentials eligible; no redirect chain or default grace",
    "rows": [
      {
        "attribute": "Strict",
        "sameSite": true,
        "topLevel": false,
        "safe": false,
        "secure": true,
        "credentialsEligible": true,
        "expected": true
      },
      {
        "attribute": "Lax",
        "sameSite": false,
        "topLevel": true,
        "safe": true,
        "secure": true,
        "credentialsEligible": true,
        "expected": true
      },
      {
        "attribute": "Lax",
        "sameSite": false,
        "topLevel": true,
        "safe": false,
        "secure": true,
        "credentialsEligible": true,
        "expected": false
      },
      {
        "attribute": "Lax",
        "sameSite": true,
        "topLevel": false,
        "safe": false,
        "secure": true,
        "credentialsEligible": true,
        "expected": true
      },
      {
        "attribute": "None",
        "sameSite": false,
        "topLevel": false,
        "safe": false,
        "secure": true,
        "credentialsEligible": true,
        "expected": true
      },
      {
        "attribute": "None",
        "sameSite": false,
        "topLevel": false,
        "safe": false,
        "secure": true,
        "credentialsEligible": false,
        "expected": false
      }
    ],
    "sameSiteMeansSameOrigin": false,
    "defaultLaxGraceModeled": false
  },
  "boundaries": {
    "httpOnlyStopsEligibleCookies": false,
    "corsDenialProvesNoRequest": false,
    "tokenValidGrantsObjectPermission": false,
    "metadataProvesHumanIntent": false
  }
}
profile
Harmless reading-view action and before/desired state; token alias is not a secret.
rows
Session, provenance and action permission produce separate results.
provenancePolicy
Exact origin and session-bound token are selected controls.
fallbackRows
Absent metadata creates no trusted-origin assumption.
sameSite
Explicit attribute/eligibility model; not a browser cookie test.

Inert boolean/state table; no real cookie, CSRF token or business action executes.

Two reality checks

HttpOnly cookies are not attached to CSRF requests.

HttpOnly limits script reading; eligible attachment and intent validation are separate.

A valid CSRF token authorizes all object actions.

Object/tenant/action permission still follows provenance/session binding.

YOUR TURN

Work through this story.

Predict the outcome, find the evidence boundary, and explain it in your own words.

Session, token and exact-origin conditions pass, but actionAuthorized=false and objectTenant=tenant-B. Does the reading view change?

  1. Yes. A bound token grants writes to every object.
  2. No. Provenance passes, but the action is denied and list is retained.
Read the explained answer

No. Provenance passes, but the action is denied and list is retained. — The permission-denied row has expectedProvenance=true and expectedAccepted=false. Passing CSRF conditions does not grant tenant/action permission.

The sibling origin is same-site and the token is bound. Does this exact-origin policy accept provenance?

Selected lesson artifact fields; teaching example

rows[2].sourceOrigin
https://notes.example.org
rows[2].metadata
same-site
rows[2].tokenBound
true
rows[2].expectedProvenance
false
provenancePolicy.requireExactOrigin
true
  1. No. expectedProvenance=false.
  2. Yes. Same-site makes every sibling origin equally trusted.
Read the explained answer

No. expectedProvenance=false. — notes.example.org is not the target atlas.example.org origin. This policy requires an exact origin; same-site metadata does not satisfy it.

The browser may automatically carry an eligible cookie. Why is session recognition not user intent, and what does this policy do when metadata is missing?

Read the explained answer

A cookie can help recognize the session, but alone does not prove the user intended this action. This policy requires a present session-bound token and an exact origin. Missing metadata uses the configured token+exact-origin fallback; a null or absent origin is not accepted. Object/action permission is still required after valid provenance. HttpOnly does not stop eligible cookie sending, and CORS denial does not prove no request was sent.

□ I did not treat session recognition as user intent.

□ I applied the defined metadata fallback and kept object permission separate.

Open the application console · request / response / browser
Also open request, URL, cookie and DOM examples

Sources and scope

  • OWASP — CSRF PreventionIntroduction; Synchronizer Token Pattern/transmission; signed double-submit session binding · Fetch Metadata server policy/fallback; SameSite limitations; source/target Origin verification; interaction-based defense
  • MDN — Set-CookieAttributes: HttpOnly and SameSite Strict/Lax/None; explicit Lax versus default grace; Secure
  • W3C — Fetch Metadata Request Headers§2.1–2.3 Sec-Fetch-Dest/Mode/Site; valid values and ignore invalid; §2.3 source/target relation