Skip to content

compute site-for-cookies from ancestor chain of a Frame - #3293

Merged
karlseguin merged 4 commits into
mainfrom
nikneym/samesite-strict-bypass
Sep 1, 2026
Merged

compute site-for-cookies from ancestor chain of a Frame#3293
karlseguin merged 4 commits into
mainfrom
nikneym/samesite-strict-bypass

Conversation

@nikneym

@nikneym nikneym commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

The site-for-cookies were computed from the immediate parent Frame, which allow sending a cookie that's SameSite=Strict from 2 levels deep under. Directly from RFC6265bis, this PR essentially implements (except for step 4, we skip host-less ancestors):

Given a Document (document), the following algorithm returns its
"site for cookies":

  1. Let top-document be the active document in document's navigable's
    top-level traversable.

  2. Let top-origin be the origin of top-document's URI if top-
    document's sandboxed origin browsing context flag is set, and
    top-document's origin otherwise.

  3. Let documents be a list consisting of the active documents of
    document's inclusive ancestor navigables.

  4. For each item in documents:

    1. Let origin be the origin of item's URI if item's sandboxed
      origin browsing context flag is set, and item's origin
      otherwise.

    2. If origin is not same-site with top-origin, return an origin
      set to an opaque origin.

  5. Return top-origin.

@nikneym
nikneym force-pushed the nikneym/samesite-strict-bypass branch 4 times, most recently from a91443d to dbf80e5 Compare August 27, 2026 07:03
@nikneym
nikneym requested a review from karlseguin August 27, 2026 07:05

@karlseguin karlseguin left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The same logic should be applied to document.getCookies and Workers then?

@karlseguin karlseguin left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can be merged once the comments are corrected.

Comment thread src/browser/webapi/storage/Cookie.zig Outdated
is_navigation: bool = true,
prefix: ?[]const u8 = null,
origin_url: ?[:0]const u8 = null,
// null means there is no initiating document (a browser-initiated

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but browser-initiated requests do pass a cookie_origin . This comment seems wrong then? So now I'm curious when it is/should be null?

Comment thread src/browser/webapi/storage/Cookie.zig Outdated
const origin_url = origin_url_ orelse return true;
const origin_host = URL.getHostname(origin_url);
pub fn areSameSite(maybe_origin_url: ?SiteForCookies, target_host: []const u8) bool {
// No initiating document (browser-initiated request).

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Repeats a (I think wrong) comment

Comment thread src/browser/webapi/storage/Cookie.zig Outdated
// .none is the site-for-cookies of a frame whose ancestor chain contains
// a cross-site document. Even though the target here is the cookies' own
// site, the request is cross-site: Strict is withheld. (Lax still rides
// navigations; whether a subframe load should count as one is #240.)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Took me a bit to find the #240 reference. I don't think a bare hashtag to a different project is useful.

nikneym and others added 4 commits September 2, 2026 07:19
The site for cookies were computed from the immediate parent `Frame`, which would allow sending a cookie that's `SameSite=Strict` from 2 levels deep under. Directly from RFC6265bis, this PR essentially implements (except for step 4, we skip host-less ancestors):

   Given a Document (document), the following algorithm returns its
   "site for cookies":

   1.  Let top-document be the active document in document's navigable's
       top-level traversable.

   2.  Let top-origin be the origin of top-document's URI if top-
       document's sandboxed origin browsing context flag is set, and
       top-document's origin otherwise.

   3.  Let documents be a list consisting of the active documents of
       document's inclusive ancestor navigables.

   4.  For each item in documents:

       1.  Let origin be the origin of item's URI if item's sandboxed
           origin browsing context flag is set, and item's origin
           otherwise.

       2.  If origin is not same-site with top-origin, return an origin
           set to an opaque origin.

   5.  Return top-origin.
Also updates matchCookies/onCookieChanged from the hard-coded "same-site + navigation" to areSameSite(exec.siteForCookies(), host) and is_navigation=false.
@karlseguin
karlseguin force-pushed the nikneym/samesite-strict-bypass branch from be441b5 to 07198b7 Compare September 1, 2026 23:28
@karlseguin
karlseguin merged commit eea50fe into main Sep 1, 2026
26 checks passed
@karlseguin
karlseguin deleted the nikneym/samesite-strict-bypass branch September 1, 2026 23:54
@github-actions github-actions Bot locked and limited conversation to collaborators Sep 1, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants