52

For the samesite cookie attribute I'm not clear on if I set a cookie with domain .example.com from sub.example.com with the samesite attribute, if it will be considered the same site as other.example.com.

Cookie behavior is different than CORS and I'm having trouble finding a resource that definitively clarifies this.

derduher
  • 623
  • 1
  • 4
  • 6

3 Answers3

55

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.

ilikebeets
  • 2,646
  • 15
  • 21
  • Do you know whether this is only true if the cookie domain is set to `.mysite.com` or is it always true for any (public suffix + 1) combo even if the cookie domain is not set and thus defaults to the issueing host name? – mackie Jan 15 '20 at 16:47
  • 1
    I realize you're (almost certainly) only the messenger, but the PSL seems an odd way of handling the `my-site.azurewebsites.net` problem. If I wanted to create a portal that allowed `user1.myportal.azurewebsites.net` and `user2.myportal.azurewebsites.net` to use it, but not see each others cookies, presumably I'd have to register `myportal.azurewebsites.net` on that list (not to mention browsers having to scan 13k+ lines to check access). Off the top of my head, specifying a _required-depth-match_ level (4 in the above case) when setting the cookie would seem better... – TripeHound Jan 21 '20 at 11:41
  • Does providing Domain property can have effect on what considers as same site? If server sends: `Set-Cookie: foo=bar; Domain=site1.example.com; SameSite=strict`, does it means then that `site2.example.com` is still considered as same site? – Sasa May 20 '20 at 18:20
  • 1
    The more I learn about web browsers, the more I die inside. – Cobolt Sep 05 '22 at 15:09
  • Agreed. They are terrifying and amazing things. These are things based on standards. Imagine all of the complexities hidden in the non-standardized functionality. – ilikebeets Sep 05 '22 at 15:46
16

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".
  1. Let "site" be "request"'s client's "site for cookies" (as defined in the following sections).
  1. Let "target" be the registered domain of "request"'s current url.
  1. 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.
  1. 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.
  1. Let "documents" be a list containing "document" and each of "document"'s ancestor browsing contexts' active documents.
  1. 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.
  1. 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.

xianshenglu
  • 261
  • 1
  • 3
2

The target URI’s “registered domain” must be an “exact match” for the request’s “site for cookies”.

You know what a “registered domain” is: The domain name you can buy or rent, i.e. one level below the public suffix.

The “site for cookies“ is usually the “registered domain” as well – here, of the request. This is true when the document is “in a top-level browsing context”, i.e. for most sites. Only for documents “in nested browsing contexts”, an additional requirement is that “the document and each of its ancestor documents’ origins have the same registered domain as the top-level site”.

In short: Subdomains don’t count. You have to compare the registrable domains.

Source: draft-ietf-httpbis-rfc6265bis-03

caw
  • 199
  • 1
  • 11