Repair two sentences the previous fix broke, and finish one it missed
Verifying the last pass found that two of its own corrections introduced fresh errors. Removing a reference to an earlier draft left the Telegram sentence circular, comparing a defect to a milder form of itself with no antecedent. And the OAuth scope sentence attached its relative clause to the wrong thing, so it read as though blocking-or-partitioning were the recommended recipe; those are different facts, since the recipe drops AUTH_SAME_SITE=none and the callback cookie then carries no attribute at all. One correction had not been applied. The line saying AUTH_SAME_SITE=none adds an unpartitioned HttpOnly JWT and contributes nothing was true of the engine the cookie jar was read on and stated of all of them; Safari drops that pair outright and Firefox delivers it either way, so it is dead weight on all three for three different reasons. Smaller: a configuration survives a browser setting instead of reaching it, the Path B task list is above its cost paragraph and not below, Firefox never holds a partitioned copy instead of not needing one, and the two remaining shorthand mentions of XSS exposure now name the token exposure they mean.
This commit is contained in:
@@ -42,15 +42,15 @@ broken.
|
||||
**Two things about this criterion are decisions, not findings, and they belong to the
|
||||
maintainer.** They are marked so neither is settled by implication.
|
||||
|
||||
The first is that it excludes OAuth, where the requirement as originally written said any
|
||||
configured provider. That is a narrowing of product scope, not a correction of fact. OAuth
|
||||
off-domain fails for the flow as built on any browser that blocks or partitions third-party
|
||||
cookies, which is Safari's default and the recommended recipe everywhere, but the routes priced
|
||||
below would change that, and
|
||||
the narrowing sits awkwardly beside `fixing #1139 must not get harder` in the Path B constraints,
|
||||
which is the same subject. Either the requirement excludes OAuth and #1139 is a separate goal
|
||||
carrying its own timeline, or the requirement keeps OAuth and is not met today. This document
|
||||
assumes the first and is not entitled to assume it.
|
||||
The first is that it excludes OAuth, where the requirement as originally written said any configured
|
||||
provider. That is a narrowing of product scope, not a correction of fact. OAuth off-domain fails for
|
||||
the flow as built on any browser that blocks or partitions third-party cookies, which is Safari's
|
||||
default; under the recommended recipe, which drops `AUTH_SAME_SITE=none`, it fails on the remaining
|
||||
browsers too. The routes priced below would change that, and the narrowing sits awkwardly beside
|
||||
`fixing #1139 must not get harder` in the Path B constraints, which is the same subject. Either the
|
||||
requirement excludes OAuth and #1139 is a separate goal carrying its own timeline, or the
|
||||
requirement keeps OAuth and is not met today. This document assumes the first and is not entitled to
|
||||
assume it.
|
||||
|
||||
The second is what counts as evidence, and the criterion is not met end to end by any single run.
|
||||
The criterion asks for sign-in, a post and a reload. The permanent suite covers sign-in, post and
|
||||
@@ -111,7 +111,7 @@ or accepts that OAuth readers sign in on the instance's own origin.
|
||||
|
||||
**Where that stands.** Master satisfies the criterion today on every browser measured except one,
|
||||
provided `AUTH_SEND_JWT_HEADER` is on. The exception is Firefox with "block all third-party cookies"
|
||||
chosen, which discards partitioned cookies too and which no configuration reaches.
|
||||
chosen, which discards partitioned cookies too and which no configuration survives.
|
||||
The server returns the token in `X-JWT` and `fetcher.ts` writes the `JWT` and `XSRF-TOKEN` cookies
|
||||
itself through `authCookieOptions`, which marks them `SameSite=None; Secure; Partitioned` in a
|
||||
third-party context. The attribute is what carries the reload, not the fact that the write happened
|
||||
@@ -168,9 +168,10 @@ The documentation gap this section named is closed by #2218. The separate-domain
|
||||
recommends `AUTH_SEND_JWT_HEADER=true` and carries the XSS trade-off in the same breath, and the
|
||||
parameter page no longer promises `SameSite=Strict` cookies and a `__Host-` prefix that
|
||||
`authCookieOptions` stopped emitting in a third-party context at #2197. That PR also measured
|
||||
`AUTH_SAME_SITE=none` out of the recommended recipe: with the header flag on it adds an
|
||||
unpartitioned `HttpOnly` JWT to third-party delivery and contributes nothing to persistence, which
|
||||
the cookie jar shows directly.
|
||||
`AUTH_SAME_SITE=none` out of the recommended recipe: on Chromium, where that jar was read, the
|
||||
header flag leaves it adding an unpartitioned `HttpOnly` JWT to third-party delivery and
|
||||
contributing nothing to persistence. Safari drops that pair outright and Firefox delivers it either
|
||||
way, so the setting is dead weight on all three for different reasons.
|
||||
|
||||
The e2e suite covers the rendering half through `TestCrossOrigin_WidgetRendersOnAnotherOrigin`,
|
||||
which proves the document loads on another origin and reports itself through postMessage across the
|
||||
@@ -189,13 +190,12 @@ exercised nowhere and cannot be until #2208 makes the Telegram API base URL conf
|
||||
without that the stack cannot answer as Telegram; `go-pkgz/auth` #316 is the change that would let
|
||||
the suite measure it. The inference itself is that the client-side writer keys off `X-JWT` on any
|
||||
auth response and not off the provider, so nothing in it distinguishes one flow from another. The
|
||||
distinction is worth keeping visible, because a criterion resting on flows the suite cannot reach is
|
||||
a milder version of the same defect in milder form: a requirement resting on what the suite cannot
|
||||
reach.
|
||||
distinction is worth keeping visible, because a criterion resting on flows the suite cannot reach
|
||||
asserts more than the evidence holds, which is the defect this section exists to avoid.
|
||||
|
||||
`ALLOWED_HOSTS` sets the CSP `frame-ancestors` and `AUTH_SAME_SITE=none` lets the server's auth
|
||||
cookies be set from any embedding domain. Those server-set cookies carry no `Partitioned`, so they
|
||||
are the ones Chromium, WebKit and Safari drop; Firefox keeps them, which is why it needs no
|
||||
are the ones Chromium, WebKit and Safari drop; Firefox keeps them, which is why it never holds a
|
||||
partitioned copy of its own. What survives the drop is the header fallback above.
|
||||
|
||||
There is a second mechanism aimed squarely at this, `AUTH_SEND_JWT_HEADER`, which returns the token
|
||||
@@ -209,7 +209,7 @@ context. The server-set cookies are untouched and still carry no `Partitioned`.
|
||||
the upstream work matter, not what excuses it: `AUTH_SEND_JWT_HEADER` defaults to false, so in the
|
||||
configuration remark42 actually ships nothing writes a partitioned cookie anywhere, and partitioning
|
||||
the server's pair is what would carry email, anonymous and Telegram off-domain without asking
|
||||
operators for a flag that costs them XSS exposure.
|
||||
operators for a flag that exposes the token to script.
|
||||
|
||||
Constraints on any frontend design:
|
||||
|
||||
@@ -231,7 +231,8 @@ Constraints on any frontend design:
|
||||
`AUTH_SAME_SITE` in `cmd/server.go` offers `default`/`none`/`lax`/`strict` with no partitioned
|
||||
axis, since `Partitioned` is a separate attribute. The first option therefore starts with a PR to
|
||||
the library. The second needs nothing upstream and already works, which is why R1 leans on it, but
|
||||
it is gated behind a flag that ships off and costs XSS exposure, so it answers the requirement
|
||||
it is gated behind a flag that ships off and exposes the token to script, so it answers the
|
||||
requirement
|
||||
without being the answer an operator gets by default
|
||||
- the popup-to-iframe handoff cannot be done in JS. The JWT cookie is `HttpOnly: true`, set in
|
||||
`Service.Set`, so the top-level popup cannot read it to hand over. The receiving end is no longer
|
||||
@@ -640,7 +641,7 @@ compiled, it is what verifies it.
|
||||
**Cost**: months to an opt-in parallel UI reads as a floor derived from the optimistic architecture,
|
||||
and the optimistic architecture does not hold. Anonymous-first is forced rather than chosen, so the
|
||||
fragment layer reproduces the entire authenticated tree rather than a delta; add the three
|
||||
subscription flows. R1 costs Path B little: the task list below retains the existing auth through
|
||||
subscription flows. R1 costs Path B little: the task list above retains the existing auth through
|
||||
`htmx:configRequest`, and `request` in `fetcher.ts` already turns `X-JWT` into the partitioned pair,
|
||||
so Path B can keep that writer or attach the same handling to a response hook.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user