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

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.

Related

Send cookies to EBS backend from CloudFront S3 frontend

I am pretty inexperienced with AWS and I have an app that uses a JWT token stored in a cookie to log in users. On page load, a GET request is made to the backend, the backend verifies the token and redirects the user to the dashboard page, which can only be accessed with a valid token. If there's no token, the backend returns a 400 error and the user stays on the home page. This works flawlessly on my local machine but not when I host the project on AWS. I believe there are no problems with how it's hosted because the backend does receive the GET request from the frontend, just without cookies, and I am adding credentials with it. The documentation talks about a Forward Cookies option and so does this video by AWS but the console has since changed and this option is no longer available. The second answer in this post suggests that the right way to do it is via custom cache and origin request policies in a distribution behavior but the example given doesn't match my use case and I haven't been able to get it working. I have tried editing the distribution behaviour and both setting "Cookies" to "All" in the legacy cache settings and using custom cache and origin request policies with the same setting but nothing works.
Axios GET request:
axios
.get(`${backendURL}/isUser`, {
withCredentials: true,
})
.then(() => router.push("/dashboard"))
.catch((error: AxiosError) => console.error(error))
Development (left) and production (right) requests
Distribution behavior unchanged (just HTTP to HTTPS redirection)
This has nothing to do with AWS and everything to do with how you are setting your cookie. You can't set a cookie from your "backend", so that your "front-end" will return it, unless they are on the same subdomain, and the cookie domain setting is set correctly.
I had some similar issues with cookies. #Warren is actually correct here.
If you want to access cookies, you'll have to setup same subdomains for your client and server applications.
However, I tried something earlier and this may work (not sure)
Map the S3 link (client) and server to cloudfront domains. This will make both the domains secure with https. (select a CF certificate, the default one). Now, set the following thing on the server side while setting cookies:
httpOnly: true
sameSite: none
secure: true
This should work I guess, give it a try. Other cloudfront setting you can change has been attached. (That is what I did)
I didn't mention on my post that I was setting the cookies on the frontend of my app, hosted at https://abcdef1234.cloudfront.net/, and trying to send the cookies to my backend, at https://api.mydomain.com/. I didn't think this was an issue but it turns out it is. To get it working, I have had to change my CloudFront distribution to use https://myapp.mydomain.com/ and the backend to set the cookie itself.

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.

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

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/

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

IE9 - asp.net cannot access cookie created for my domain by third party site

I have this weird problem in IE 9. I have a site which allows a user to login and can also be logged in by a separate website using web service in the background. When logged in, a cookie is created. In fiddler, I can see the user has logged in to my site from the third party website and the cookie is created. The third party site makes an ajax call and the cookie is created in my domain.
But when I click on a link to my site from the third party site, the login page is displayed again. I wrote a debug code that states in the page that the cookie does not exist but I can see in IE settings that the cookie does exist. The cookie expires in 24 hours.
How do I fix it? By the way, it works fine in most other browsers including IE8, IE7, Chrome.
This is similar to - IE9 Separate cookies for third party request - but there is no response there.
There is a limitation introduced in IE 9+. It isolates different zones to access each others' data. For example if a cookie is created in example.com for domain:example.com, a.example.com cannot access the cookie if their zones are different (one is intranet, one is trusted, etc.). You can check the zones in Internet Option -> Security tab.
For more information check Cookie Sharing in Cross-Zone Scenarios