- From: rifmj <notifications@github.com>
- Date: Mon, 02 Nov 2026 05:47:34 -0800
- To: whatwg/fetch <fetch@noreply.github.com>
- Cc: Subscribed <subscribed@noreply.github.com>
- Message-ID: <whatwg/fetch/issues/1965@github.com>
rifmj created an issue (whatwg/fetch#1965)
Spec: Fetch at 59afe34, [determine the same-site mode](https://github.com/whatwg/fetch/blob/59afe349913d56898c947576216f1c2579308be7/fetch.bs#L3590) and the `Set-Cookie` processing that calls it. The text dates from 1d9380b ("mostly editorial").
Read by the letter, the algorithm gives results that no browser produces. WPT `cookies/samesite/` already asserts the browser behaviour, so the tests and the text disagree.
| Case | Mode by the text | Text gives | Observed |
|---|---|---|---|
| Link from site `a` to site `b`, GET | step 2: `unset-or-less` | `SameSite=Lax` not sent | sent in all three |
| Same-origin link, GET | step 3: `lax-or-less` | `SameSite=Strict` not sent | sent in all three |
| Browser UI navigation, GET | step 2: `unset-or-less` | `Strict` and `Lax` not sent | sent in all three |
| `<img>`, `<iframe>`, or `fetch()` with `credentials: "include"`, from top-level `a` to `b` | step 6: `strict-or-less` | `Strict` and `Lax` sent | not sent in Chromium or Firefox |
| Top-level form POST from `a` to `a`, 307 to `b` | step 6: `strict-or-less` | `Strict` and `Lax` sent | not sent in any |
| Response to a top-level GET navigation sets `a=1` or `SameSite=Lax` | flag false, "Store a Cookie" rejects it | not stored | stored in all three |
Causes:
1. Step 2 (cross-site initiator) runs before step 3 (GET document), so the Lax exception for cross-site navigations is unreachable. Step 3 then also catches same-site navigations.
2. A browser UI navigation has a new opaque initiator origin in HTML ("navigate", then "top-level navigation initiator origin"). An opaque origin is not same site with anything, so step 2 treats it as cross-site.
3. No step compares the request with its client. `has cross-site ancestor` looks at parents only, so a first request from a top-level `a` to `b` reaches "return strict-or-less".
4. Redirect-taint skips a hop when the request's origin is same site with the URL before it. For the POST above the origin is `a` and the list is `[a, b]`, so the taint is not `cross-site`. Step 2 reads the first URL, also `a`.
5. `sameSiteStrictOrLaxAllowed` is true only for `strict-or-less`, while RFC 6265bis 5.7 step 18.3 notes that top-level navigations can create a cookie with any SameSite value.
Existing tests that contradict the text: `samesite/form-get-blank.https.html`, `samesite/setcookie-navigation.https.html`, `samesite/fetch.https.html`, `samesite/img.https.html`, `samesite/iframe.https.html`.
There is also an editorial point. Step 1 asserts that the method is GET or POST, but "append a request Cookie header" runs for every method. The assert should go; the remaining steps already give the right result for same-origin requests. I found no test for other methods, so I added one in web-platform-tests/wpt#64550 (`samesite/methods-beyond-get-post.html`, 4/4 in all three).
Related: #1826 tracks the integration. In httpwg/http-extensions#3150 annevk wrote "we need to change the logic to actually enable such filtering" about `unset-or-less`, and this list may help with that change. I did not propose new steps, because nested navigations and a null client need a decision from the editors.
How this was observed: Playwright 1.64.1 builds of Chromium 156, Firefox 157 and WebKit 27.2, on `*.localhost`, with `page.goto` standing in for browser UI. WebKit is left out of the subresource row: it blocks third-party cookies there, so its result says nothing about SameSite. It does not treat `localhost` as a public suffix, so its same-site cross-origin results on this setup are not used.
Drafted with AI help.
--
Reply to this email directly or view it on GitHub:
https://github.com/whatwg/fetch/issues/1965
You are receiving this because you are subscribed to this thread.
Message ID: <whatwg/fetch/issues/1965@github.com>
Received on Monday, 2 November 2026 13:47:38 UTC