Safari not sending cookie even after setting SameSite=None; Secure
Asked Answered
O

8

54

Our application uses cookies to remember user login. Every auth API call we make, the browser attaches server-set HTTPonly cookie with the API request and gets authenticated. This behaviour seems to be broken in safari after Mojave release.

I read about the cross-site cookie security implemented by safari and our server team added SameSite=None;Secure while setting the cookie. Even after that, it still doesn't work.

Set-Cookie: my_cookie=XXXXX; path=/; secure; HttpOnly; SameSite=None

Please advise or provide links from people who actually found a solution..

Otranto answered 23/10, 2019 at 14:57 Comment(0)
C
40

Versions of Safari on MacOS 10.14 and all browsers on iOS 12 are affected by this bug which means that SameSite=None is erroneously treated as SameSite=Strict, e.g. the most restrictive setting.

I've published some guidance in SameSite cookie recipes on either:

  • Using two sets of cookies to account for browsers that support SameSite=None; Secure and those that don't.
  • Sniffing the user agent for incompatible browsers and not serving SameSite=None for those requests.
Constitutionally answered 31/10, 2019 at 22:54 Comment(6)
Hello Rowan, Thanks for the reply and apologies for the late response. I've asked my server-side team to try out the guidance from the web.dev link above. Maybe this is a completely inappropriate question to ask, anyway here goes. Since millions of users are affected by the change, any news if there is a plan in future from the apple team to resolve it?Otranto
I can't speak for the Apple / Safari team. I think the original bug is the best place for those discussions.Constitutionally
Good lord. Just spent the last three days with a customer who was having the darnedest time returning from paypal because cookies appeared to be missing (thus no session to continue buying).... and they were on an older Safari/webkit than current.... this issue described the problem exactly.Handwoven
According to the bug report, it seems they don't plan to backport the fix because it's sort of intentional. Safari's cookie policy is different, and thus, somehow, it's allowed to behave differently than the other browsers when it receives an unknown property. Just Apple being Apple, in the end.Sunlit
What safari version has the fix then ?Tullius
Probably none... Safari is the new IESporulate
R
21

Safari is no longer sending cross-site cookies. So even if the cookie is set to SameSite=None it will not be sent with the third party ajax requests.

To allow sending cross-site cookies, Go to Safari > Preferences > Privacy and uncheck Prevent cross-site tracking

enter image description here

Reliquary answered 5/6, 2022 at 8:59 Comment(1)
It is more a bug than a feature. Since on the cross-site you can explicit allow the origin domain. I am still trying to find a solution for my php-pages with autologin (when loaded dynamically).Fact
G
14

The issue is not about Safari sending or not the cookie, it's about Safari not storing the cookie. This is related to a specific combination of cookie config, it's working with this setup for localhost

Set-Cookie: your=cookie; Domain=localhost; Path=/; Expires=Mon, 26 Dec 2022 12:53:02 GMT; HttpOnly; SameSite=Lax

and this setup for prod

set-cookie: your=cookie; Domain=something.com; Path=/; Expires=Thu, 22 Dec 2022 04:17:44 GMT; HttpOnly; Secure; SameSite=Lax

you need to include Domain on both and Secure for your prod (ssl) env. You can use different values for SameSite but Lax is what works for me

Gilthead answered 31/12, 2021 at 20:22 Comment(2)
Wow man, I am really grateful I have come across your answer. You literally saved my life. I had been struggling for the past 2 days at work on this problem and I tried many things and could not seem to find any solution until I found your answer. I appreciate people like you! :)Kalamazoo
This has been driving me crazy for days and this is the only solution that's worked. Thank you!Trimeter
A
13

This is an issue also in Safari 14. Safari is not sending third-party cookies by default anymore. This is because they introduced Privacy Preference: "Prevent cross-site tracking" which is turned on by default. So if you set your cookies with SameSite=None; Secure they still don't be set and sent cross-domain.

Athelstan answered 15/7, 2021 at 10:18 Comment(2)
Is there any solution/workaround to this?Hypocaust
A workaround is to proxy the cross-site API/server you are interacting with into your own site (i.e. have your server proxy /api/* requests to the other server). Or if you control the other server, you can host it under a subdomain or adjacent domain to your site, and Safari will then consider it to be "same site".Blackmon
M
2

I tried disabling "Prevent cross-site tracking" option in MAC OS (i.e., Settings > Safari > Privacy & Security > Prevent Cross-Site Tracking - disabled) and iframe started to work. I know this is not a fix but might be a quick workaround for a short time.

Matthew answered 2/9, 2021 at 6:35 Comment(1)
Please add further details to expand on your answer, such as working code or documentation citations.Apophthegm
B
2

As mentioned by several answers already, this appears to be an indended behaviour introduced in Safari wherein it deviates from the web spec implemented by other browsers.

The "Prevent cross-site tracking" setting, which is enabled by default, causes all cross-site cookies to be rejected, regardless of SameSite=None; Secure, which other browsers would otherwise accept.

Workarounds:

  • If you control the cross site API, you can host it on a subdomain or sibling domain to your site. It appears that so long as your site and the API have a common parent domain, Safari will treat it as "same site" and allow the cookie. I don't have documentation to support this, but I tested on Safari 17.
  • Have your site's server proxy the cross site API (e.g. proxy /api/* requests to the other server) thusly making the API requests "same site". How you do this depends on the solution you use to host your site.
Blackmon answered 19/10, 2023 at 0:9 Comment(0)
O
1

I have been struggling with figuring out cookies since first starting work on our website. I finally figured them out though. On our server we use firebase sessions in an express app where they are initialized like so:

app.use(
    session({
        name: "myCookie",
        store: new FirestoreStore({ dataset: firestore }),
        secret: process.env.SESSION_SECRET as string,
        resave: false,
        proxy: true,
        cookie: {
            maxAge: 1000 * 60 * 60 * 24 * 365 * 10,
            httpOnly: true,
            secure: process.env.PROD == "true",
            sameSite: 'lax',
            domain: "mydomain.com"
        },
        saveUninitialized: false,

    })
)

The settings for the cookie did not matter for our iOS application, but for our website we had several hurdles. To get it to work on the desktop website browsers and android we had to set the cookie to secure and httpOnly. However, for iOS mobile browsers the cookie was failing to set. The issue was because mobile browsers on iOS only use first-party cookies. I had to add a CNAME for our API server which was a subdomain of our website and direct API calls to that CNAME. Then, in our API had to specify the domain for the cookie (which you must do explicitly for sub domains to be allowed in the cookie). This resolved it.

Octosyllable answered 3/5, 2023 at 20:33 Comment(0)
L
0

For applications coded in Ruby (specifically, Rails, Sinatra, or anything atop Rack), the RailsSameSiteCookie gem solves this and related issues quite nicely. The code reads like a near translation of the pseudocode in the Chromium discussion without the brittle regex's.

Liberec answered 20/2, 2020 at 19:30 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.