Cookies without "SameSite" attribute are sent on different sub domains - google-chrome

So I've read about Chrome 80's cookies defaulting to SameSite=Lax and like the rest of you, I'm now trying to mesure the impact this will have on my site.
The site I'm running is split on several sub-domains and each of them uses their own cookie. It looks like this:
first-site.domain.com uses Cookie1 (path=/; secure; httponly)
second-site.domain.com uses Cookie2 (path=/; secure; httponly)
Since these cookies do not specify the SameSite attribute, they are supposed to be treated as Lax on Chrome 80 and therefore should be limited to same-site requests (unless it's a top level navigation).
Then, according to SameSite cookies explained:
If the user is on your-project.github.io and requests an image from
my-project.github.io that's a cross-site request.
So when I enabled the “SameSite by default cookies” and “Cookies without SameSite must be secure” flags, I was surprised to observe that when first-site.domain.com embeds second-site.domain.com in a frame, Cookie2 was still being sent to second-site.domain.com, which seems contradictory.
Surely I must have misunderstood something, but at the moment, I'm still puzzled.
Note: I've verified that when I embed second-site.domain.com in a frame on anotherdomain.com, the cookies are not sent by the browser (as expected).

If "domain.com" is on the public suffix list, then subdomain1.domain.com and subdomain2.domain.com are considered different sites. Otherwise, they are considered the same site.
The relevant notion of "site" when it comes to SameSite cookies is the eTLD+1 (effective Top Level Domain + 1 label). An effective Top Level Domain is something like .com or .co.uk or .github.io. All the eTLD's are listed on the public suffix list.
An eTLD+1 is the effective Top Level Domain plus the 1 label immediately to its left. The eTLD+1 is also called the "registrable domain". The intuition is that two different eTLD+1's are controlled by different entities, and everything that is a subdomain of the same eTLD+1 is controlled by the same entity. For example, mysite.github.io is a different eTLD+1 than yoursite.github.io, because I cannot modify your site, and you can't modify mine. On the other hand, the same company owns both subdomain1.domain.com and subdomain2.domain.com and modify both sites.
If the eTLD+1's are the same for two domain names, they are considered the same site for the purposes of SameSite cookies.

Related

SameSite cookies, frames, sub domains and redirections

The SameSite concept for Cookies is definitely a hard one to grasp...
In preparation for Chrome 80's changes, I'm trying to measure the impact of the absence of SameSite attribute on my cookies. I have the following configuration:
User initially accesses main.mysite.com
main.mysite.com sets SomeCookie (Set-Cookie: SomeCookie=value; path=/; secure; httponly) and redirects to auth.mysite.com
User authenticates on auth.mysite.com and is redirected back to main.mysite.com (POST request)
Because redirections between main.mysite.com and auth.mysite.com are considered as same site and because the absence of SameSite attribute is treated as SameSite=Lax by Chrome 80, this works just fine.
However, when main.mysite.com is embedded in a frame on a page hosted on another site (say othersite.com), SomeCookie is not sent back to main.mysite.com at step 3:
Is this normal and why?
The answer above is just incorrect... Let me clear up some confusions.
1. When are 2 sites the "same site" for the purposes of SameSite?
Regardless of the Domain attribute of a cookie, two sites are considered the same when their eTLD+1 (aka registrable domain) are the same. See my answer here for a more detailed explanation.
So in this case, assuming the eTLD is ".com", we would consider auth.mysite.com and main.mysite.com to be the same site because the eTLD+1 is mysite.com for both of them. On the other hand, anything.mysite.com and othersite.com are always cross-site. This is true whether it is a top-level navigation or a subresource request (like an image or a document in an iframe).
2. What does the Domain attribute mean?
If a cookie is set with Set-Cookie: cookiename=cookievalue; Domain=mysite.com, then the cookie will be sent on requests to any domain matching *.mysite.com (i.e. all subdomains).
This is a way to adjust the scope of a cookie. For example, you could use Domain=mysite.com for a global cookie that all of your domains care about, and Domain=corp.mysite.com for a cookie that all of your company's internal domains care about (but not your external-facing domains, for example).
The default (for cookies that don't explicitly set a Domain attribute) is that cookies are sent only to the domain that set the cookie. (No subdomains.)
You cannot set a Domain attribute that does not match the URL of the request.
(Also, there is no such thing as an "origin" attribute of a cookie.)
3. So what does Domain have to do with SameSite?
Nothing. They are independent cookie attributes. Domain doesn't care about the same-site/cross-site context, and SameSite doesn't care about domain/subdomain scope of the cookie.
4. When mysite.com is embedded in an iframe on othersite.com, why are default-Lax cookies not sent?
This is considered a cross-site context, because the site in the user's URL bar is othersite.com whereas the request is made to mysite.com, and these have two different eTLD+1's.
Because it's in an iframe, this is not a top-level navigation, so all cross-site requests will exclude SameSite cookies.
If it were a top-level navigation (user clicks on a link that takes them from othersite.com to mysite.com), then the request method would matter. In the vast majority of cases this would be a GET request, so a cookie in Lax mode would be sent.
Hope this helps! You can refer to the latest version of the spec for more details.
First of all, I'm assuming that the domain attribute of the cookie is set as auth.mysite.com and not as .mysite.com. If domain attribute of the cookie is auth.mysite.com, then auth.mysite.com and main.mysite.com are not considered as SameSite.
You need to set cookie domain property to .mysite.com so that browser can see the shared origin between the two sites and consider them as same site.
My response to your question: Yes, it is normal that SomeCookie is not sent back to main.mysite.com, when you are using iframes, for the following reasons:
In the absence of sameSite attribute, the value of the attribute is treated as Lax
SameSite=Lax is almost exactly the same as SameSite=Strict, except the fact that SameSite=Lax also allows sending cookie along 'Top-level navigations'. Top-level navigation is the type of navigation when the value inside the URL bar changes. iframe context is not interpreted as a top-level navigation.
If you want make your cookies available to iframe context, you can do two things:
Set sameSite attribute value to none and at the same time, set secure attribute value to true In this way, you explicitly tell the browser your intention ( which is cross site authentication ).
If you set the domain attribute of cookie to .mysite.com, then you can even work with SameSite=Strict, i.e. they will be interpreted as the same site so no extra caution will be required.

Fix Not Working: A cookie associated with a cross-site resource was set without the `SameSite` attribute

I maintain an old ASP site for my company.
We have two different domains, A and B. Domain B appears in an iFrame, and we've been getting the SameSite warning.
The solution seems to involve adding "SameSite=None; Secure" to the header.
I added those values, and they show up in Chrome dev tools:
Despite the change:
The warning still shows up.
When enabled, the SameSite experimental features still block the cookie on the host site.
Anyone know what I might be doing wrong here?
What you have showing there is two cookies, one with the session id, and another whose name is SameSite. Neither of these have any SameSite attribute (hence the blank space under the SameSite column).
You're not supposed to set a separate cookie for SameSite=None. SameSite is a cookie attribute, which is meant to be attached to the cookie it refers to.
The way you use it is like this:
Set-Cookie: sessionid=12345; SameSite=None; Secure. Note that this is a single Set-Cookie header. If you use two separate Set-Cookie lines, the browser will interpret it as two separate cookies, which is not what you want.

Why does Google Chrome not recognize my SameSite cookie?

I'm trying to explore how Google Chrome handles SameSite cookies. So by using the console (ctrl+Shift+J), I added an aditional key-value pair for the cookie of a certain website I have an account on. I inputted the following code:
document.cookie="SameSite=strict"
I checked the remaining cookie and all original key-value pairs are still there, along with the newly added "SameSite=strict" pair.
Now, the problem is that Chrome doesn't act like it is supposed to according to the specification of the SameSite cookie. For example: when I go to wikipedia.org and click on a link that directs me to the website of the cookie, I'm logged in. Normally I would not be logged in, because Chrome isn't supposed to send along the cookie due to the "SameSite=strict" pair.
Am I overlooking something?
SameSite is not a cookie value. It's a cookie flag, like httpOnly and secure. So you cannot set it like document.cookie="SameSite=strict", because that sets a value.
Try with
document.cookie="mycookie=myvalue;SameSite=strict"
You can then observe in Chrome DevTools on the Application tab under Cookies that your cookie is in fact set as SameSite=strict, as opposed to just a plain cookie.

how to set the X-Frame-Options in a content hosted by github?

I want a html file to be loaded as iframe by any url, it's hosted by Github ..
This solution doesn't work :
<?php
header('X-Frame-Options: GOFORIT');
?>
And I suppose that we can't apply this one (mod_headers), so is there a way to do that ?
Support answer :
We block iframes to prevent clickjacking attacks against our users. We
do this by sending the "X-Frame-Options: deny" header for every page.
Clickjacking is a legitimate attack vector and at this time we do not
have plans to remove the "X-Frame-Options: deny" header or allow
exceptions for non-GitHub owned properties. It's unfortunate that such measures are necessary, but we have a responsibility to take all practical steps to protect our users.
As jeum explained, no dice with an iframe, it just won't work. If you could override the directive with a meta tag, it might work, but you can't:
Note that this token must be sent as a HTTP Header, and the directive will be ignored if found in a META HTTP-EQUIV tag.
So, it doesn't work with an iframe. But does it really have to be an iframe? Because loading a script will still work, so you could do something like this:
Script on your site (let's call it load_content.js):
var node = document.createElement('div')
node.innerHTML = '{place your code encoded as a JS string here}'
document.appendChild(node)
And then use it from other sites like this:
<script src="{URL to load_content.js}"></script>
Of course, this has some security implications for the sites on which you use it, but it might be sufficient for your needs.
OTOH, why don't you just host that content elsewhere? A small virtual server doesn't exactly cost a lot (unless you want tons of RAM and harddisk space) (I pay maybe 6€ per month or so), and even if you can't afford to pay any money, there are sites that let you host a few html pages for free, I think.

How do browsers interpret hrefs that start with "http:/"?

Some of my users are creating links that look like
<a href='http:/some_local_path'>whatever</a>
I've noticed that Firefox interprets this as
<a href='/some_local_path'>whatever</a>
Can I count on this occurring in all browsers? Or should I remove the http:/s myself?
This is an unusual URL, but is not invalid. The URL spec says that omitted components are defaulted from the base url, which can be provided explicitly in a <base> tag, or absent that, the current URL of the page.
When a browser sees /some_local_path, it is missing a scheme and a host, so it takes them from the base url. When your users put http:/some_local_path, it has an explicit scheme, but is missing a host, so the host defaults to the base url. If your page is an http: page, then the two URLs will be interpreted identically.
All that said, those URLs are almost certainly not what your users intended. You'll be helping them if you point out their error.
It's always best to validate data entered by users. Inevitably, you'll get something unexpected.