For SameSite cookie with subdomains what are considered the same site?

The 'Site' in SameSite refers to a the combination of second level domain mysite.com and top level domain mysite.com.

This means that a requests from login.mysite.com to cdn.mysite.com would be considered a same-site request.

BUT... as you might imagine it does not end there. There is the Public Suffixes List which slightly changes this validation behavior.

Why? Well, because there are a number of sites where end users, and not the registrar or domain owner, control part of the domain (the sub-domain). E.g. my-site.azurewebsites.net.

From a privacy and security perspective cookies scoped to my-site.azurewebsites.net should definitely not be sent to your-site.azurewebsites.net. And, since there is no algorithmic way for your browser to determine if a particular URL is of this type, the Public Suffixes List was created for browsers to change their same-site validation behavior. Hence, azurewebsites.net is listed on the Public Suffixes List.

So, for sites on the Public Suffixes List a request from my-site.azurewebsites.net to your-site.azurewebsites.net would be considered cross-site.


Let me explain the specification.

The definition of "same-site" is :

A request is "same-site" if its target's URI's origin's registered domain is an exact match for the request's client's "site for cookies", or if the request has no client. The request is otherwise "cross-site".

For a given request ("request"), the following algorithm returns "same-site" or "cross-site":

  1. If "request"'s client is "null", return "same-site".

  2. Let "site" be "request"'s client's "site for cookies" (as defined in the following sections).

  3. Let "target" be the registered domain of "request"'s current url.

  4. If "site" is an exact match for "target", return "same-site".

    1. Return "cross-site".

As you can see, the core is to compare site for cookies with registered domain.

Let's start from registered domain.

An origin's "registered domain" is the origin's host's public suffix plus the label to its left. That is, for "https://www.example.com", the public suffix is "com", and the registered domain is "example.com". This concept is defined more rigorously in PSL, and is also known as "effective top-level domain plus one" (eTLD+1).

[PSL] "Public Suffix List", n.d., https://publicsuffix.org/list/.

However, as you can see in https://publicsuffix.org/list/, github.io is also in the list which means it is a public suffix. Thus, the registered domains of https://me.github.io and https://you.github.io are me.github.io and you.github.io while the registered domains of https://me.example.com and https://you.example.com are both example.com.

The reason is that github.io is in the https://publicsuffix.org/list/ while example.com is not in the https://publicsuffix.org/list/.

Let's keep moving. So, what is the "site for cookies"?

We can find it's definition here

The URI displayed in a user agent's address bar is the only security context directly exposed to users, and therefore the only signal users can reasonably rely upon to determine whether or not they trust a particular website. The registered domain of that URI's origin represents the context in which a user most likely believes themselves to be interacting. We'll label this domain the "top-level site".

For a document displayed in a top-level browsing context, we can stop here: the document's "site for cookies" is the top-level site.

For documents which are displayed in nested browsing contexts, we need to audit the origins of each of a document's ancestor browsing contexts' active documents in order to account for the "multiple- nested scenarios" described in Section 4 of [RFC7034]. A document's "site for cookies" is the top-level site if and only if the document and each of its ancestor documents' origins have the same registered domain as the top-level site. Otherwise its "site for cookies" is the empty string.

Given a Document ("document"), the following algorithm returns its "site for cookies" (either a registered domain, or the empty string):

  1. Let "top-document" be the active document in "document"'s browsing context's top-level browsing context.

  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 containing "document" and each of "document"'s ancestor browsing contexts' active documents.

  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"'s host's registered domain is not an exact match for "top-origin"'s host's registered domain, return the empty string.

  5. Return "top-origin"'s host's registered domain.

The related definitions are listed above.

We can end with an example.

For instance, a request from https://me.github.io to https://you.github.io is cross site if the URI displayed in the user agent's address bar is https://me.github.io.

However, a request from https://me.example.com to https://you.example.com is same site if the URI displayed in the user agent's address bar is https://me.example.com.

The difference is that the registered domains of https://me.github.io and https://you.github.io are me.github.io and you.github.io while the registered domains of https://me.example.com and https://you.example.com are both example.com.

Tags:

Cookies

Csrf