Reading cookies with "Samesite=None;Secure" from iframe in Safari 13 - cookies

I have an iframe where I use cookie authentication. The cookie is set normally on my domain when users log in. I use SameSite=None;Secure. The problem is that when a third party website embeds an iframe from my domain, my authentication cookie is not passed so the iframe cannot authenticate the user.
This works fine in Chrome and Firefox, but doesn't work in Safari (and it used to work up until about a month ago)
I'm aware of the Webkit bug with SameSite=None, which was supposedly fixed in Safari 13. I know that Safari is no longer allowing iframes to set third party cookies (this has been the case for years, so I don't see how it could be related to this recent change). However, I'm not trying to set a cookie - I just want to read it. Until recently, this was possible (see this SO question).
Until Safari 13, there was a workaround that allowed people to set third-party cookies by redirecting the top page to the cookie-setting domain and then going back to the original page. In this case the iframe would be able to see the cookie (because again, the iframe couldn't write but it could read cookies.
I tried setting a secondary cookie with no SameSite attribute, as these were supposed to work, but it's still not being sent.
Is Safari now completely dropping cookies regardless of whether SameSite is set or not? If so, why did they bother to fix the SameSite bug? Something doesn't add up.
Update:
It seems to be related to Apple's ITP 2, which sets strict standards on third-party cookies and even discriminates between domains based on which domains they deem likely to do bad tracking: https://www.seerinteractive.com/blog/what-is-intelligent-tracking-prevention/
So from what I've been gathering, these seems to be no way to circumvent the situation.
Update 2:
I think I might have found a reliable solution in Webkit's Storage Access API: https://webkit.org/blog/8124/introducing-storage-access-api/

Related

Unable to access site cookie after LTI Launch

I have a small LTI application that integrates with canvas, and after the LTI launch I can't access the cookie. This is failing in Safari (always) and Chrome (sometimes).
I am forcing the SameSite=LAX field of the cookie.
I'm not sure what else I should try.
There have been numerous changes in Chrome (and other browsers) regarding cookies and iframe.. For LTI 1.3 launches this is extra difficult because of how you need to track the state of the launch in the cookie while processing the OIDC flow.
The basics of what is changing is there is now a 'SameSite' cookie policy, where Only cookies set as SameSite=None; Secure will be available in third-party contexts, provided they are being accessed from secure connections. So marking the cookies as Secure and HTTP-Only is a must in addition to the SameSite=None
Also in Safari, the third-party frame will have to request access to the storage API before the cookie will be accessible.
Firefox is using a partitioned approach to the storage, and so the frame will behave as normal unless you then open your application as a new window then the cookie store may or may not follow depending on how the new window was created.
Cookie Status is an excellent resource to track how third party cookies work in the different browsers and what you should change to make it work.

Browser blocks cross domain iframe cookies

I have a forum-like component which I use in an iframe on other websites. This component uses django-allauth for authentication with Facebook and Twitter. Everything worked fine but now the authentication stopped working some time ago. When I look at the cookies in my browser, the cookies from Facebook/Twitter which are set by the iframe, are not loaded. Although, the cookies from the component itself are set.
The authentication still works when I load the iframe on a website which is on another subdomain of the component itself.
Tool on another subdomain (working):
https://shop-sandbox.adbuddy.be/discussie/
Tool on a totally different domain (not working):
https://mama-calinka.webbuddy.be/discussie/
I guess this problem had something to do with CORS-headers but nothing I've tried helped. Can someone help me with this problem please?
If this stopped working only very recently, it could be related to the Chrome's recent breaking change , that in case cookie's attribute SameSite is not explicitely set it defaults to SameSite = Lax, which prevents your browser in cross site requests to sent the cookie over.
I checked your https://shop-sandbox.adbuddy.be/discussie/ - there are many cookies with SameSite empty.
There could be a couple of more reasons, why a browser ignores a cookie in the request and I tried to sum all of them in my blog here

Safari not including cookies in request, but Safari incognito does?

So with my app I allow our users to set their own custom domiain which points to our hosted app on netlify. This works fine, but now the frontend is obviously talking to an api which lives on a different domain.
On the auth cookie I send back from the api, I have SameSite=None which works on all other browsers except for safari where the request does not include the cookie. However, if I go on Safari in incognito, it does include the cookie on the request? My question is:
Why does this work in safari incognito and not normal?
Is there a way to make this work in normal safari?
Here is a more thorough example:
front end:
customersdomain.com
api:
api.myapp.com
Cookie
x-refresh: <cookie_val>
SameSite: none
HttpOnly: true
Secure: true
expires: 1 month
domain: api.myapp.com
My cors has allow credentials set as well and in the request I have credentials set to include.
In Safari 13.1, in order for third party requests to have access to credentials/cookies, you must use the Storage Access API to request access, via an iframe.
This may affect the workings of your app considerably. Please read WebKit's recent blog post for more information about the latest changes to their Intelligent Tracking Prevention.
Before Safari 13.1, there were some temporary compatibility fixes as detailed here to allow for third party requests to have access to cookies. My guess is that the third party domain was flagged by Safari on your device as being a domain that has the potential to track users, and blocked from having access to cookies by default. The domain will remain blocked for as long as you don't clear the cache on Safari. By using an incognito window, the domain was no longer blocked for that session.
SameSite=None compatibility was added to Safari 13, so this shouldn't have contributed to any of your issues.

Why do I see cookies I did not set?

I occasionally receive warnings from PHPIDS about certain cookies, and on further examination, it appears that a particular client keeps sending me cookies that I did not set, e.g. mp_d21cb8a9f34838c02aeec897b3728a94_mixpanel.
How is that possible? It was my understanding that cookies are only sent back to the server/domain that set it, and I do not use mixpanel and to my knowledge did not set that cookie.
I understand that mixpanel is a web tracking tool, but I do not use it (I use Google Analytics). I have no other users on my server/domain, I have no affiliate ads/banners on my site, and I do not support user generated content. So I am fairly certain that my server did not set that cookie, but then why does the client browser (IE11) keep sending me that cookie? The user's behavior seems legitimate, i.e. it appears to be no bot or script.
Do I have a fundamental misunderstanding how cookies work? Can some other server set cookies for MY domain? Any ideas how this comes about? Are there known browser bugs that mixes up cookies?
Regards,
Arno

CORS, withCredentials and third party cookies

I'm trying to do a CORS GET that sends the cookie along with it. I've set all the headers (access-control-allow-origin, access-control-allow-credentials, access-control-allow-headers) in the server and am using withCredentials: true and crossDomain: true in the jquery ajax request. Everything works when I tell my browser to allow third-party cookies. Is there any way to do this without forcing visitors to allow third party cookies? I've even tried redirecting the user and redirecting back, but CORS will refuse to send the cookie along. :/
I've tried doing the CORS request via ajax, as well as via an iframe.
I don't think it is possible. See my (old but relevant) blog post on this.
The only bullet-proof way is to use 1st-party cookies (that is, open window in a top-level window like a separate tab, or redirect current window).
In some cases it is not necessary though. Browsers have slightly different notions of what third-party cookie is, and default behavior is also different. This post has a nice overview on these details. So in some cases you could do tricks to enable (or at least detect) use of cookies on the page.
Other workarounds include putting one server under a subdomain of the other (subdomains are usually not considered 3rd-party), or changing the flow so that the user is authenticated by other means than cookies.
if you set cookie (origin 2 set cookie) you should know third party cookie will be used, but if you only get cookie (only send cookie for origin 2 without setting in response) there is no reason third party cookie play a role.
so i think you set a cookie in origin 2 and because of that force you enable third party cookie.
Note that cookies set in CORS responses are subject to normal
third-party cookie policies. In the example above, the page is loaded
from foo.example but the cookie on line 19 is sent by bar.other, and
would thus not be saved if the user's browser is configured to reject
all third-party cookies.
Cross-Origin Resource Sharing mozilla.org