Safari在设置了SameSite=None; Secure后仍未发送cookie

50
我们的应用程序使用 cookie 来记住用户登录信息。每当我们进行身份验证 API 调用时,浏览器都会将服务器设置的 HttpOnly cookie 附加到 API 请求中并进行身份验证。但是,在 Mojave 版本发布后,这种行为似乎在 Safari 中出现问题。
我了解到 Safari 实施了跨站点 cookie 安全性,并且我们的服务器团队在设置 cookie 时添加了 "SameSite=None;Secure"。但即便如此,它仍然不起作用。
请提供建议或者提供实际找到解决方案的人们的链接。 Set-Cookie: my_cookie=XXXXX; path=/; secure; HttpOnly; SameSite=None
8个回答

40

受到此漏洞影响的是 MacOS 10.14 上的 Safari 版本和 iOS 12 上的所有浏览器,这意味着SameSite=None被错误地视为SameSite=Strict,例如最严格的设置。

我在SameSite cookie recipes中发布了一些指南,包括:

  • 使用两组 cookies 来处理支持SameSite=None; Secure 和不支持此选项的浏览器。
  • 对于不兼容的浏览器,通过嗅探用户代理来检测,并在这些请求中不提供SameSite=None

1
你好,Rowan。感谢您的回复,抱歉回复晚了。我已要求我的服务器端团队尝试上述web.dev链接中的指导。也许这是一个完全不恰当的问题,但还是问一下吧。 由于数百万用户受到此更改的影响,是否有消息称苹果团队未来有计划解决这个问题? - DieOnTime
我无法代表苹果/Safari团队发言。我认为最好讨论这个问题的地方是原始bug。 - rowan_m
4
天啊!刚刚花了三天时间帮助一位顾客解决问题,他因为缺少 cookie(无法继续购买)而无法从 PayPal 返 回……由于他使用的是比现在更旧版本的 Safari/Webkit 浏览器,所以出现了这个问题。这个问题完美地描述了他的困境。 - IncredibleHat
1
根据错误报告,似乎他们不打算将修复程序回溯,因为这是有意的。Safari的Cookie策略不同,因此,在接收到未知属性时,它可以以与其他浏览器不同的方式运行。最终,这只是苹果公司的风格。 - igorsantos07
6
那么,哪个Safari版本有修复呢? - Frank Q.
1
可能没有... Safari 是新的 IE - Nicu

17

Safari不再发送跨站点Cookie,因此即使将Cookie设置为SameSite=None,它也不会随第三方ajax请求一起发送。

要允许发送跨站点Cookie,请前往 Safari > 首选项 > 隐私 并取消选中 防止跨站点追踪

enter image description here


这更像是一个漏洞而不是一个功能。因为在跨站点上,您可以显式允许源域。我仍在尝试为我的具有自动登录功能的PHP页面找到解决方案(当动态加载时)。 - Adriano

13

在Safari 14中也存在此问题。Safari不再默认发送第三方cookie。这是因为苹果引入了隐私设置:“防止跨站追踪”,默认开启。因此,如果您使用 SameSite = None; Secure 设置cookie,则仍然无法在跨域时发送。


4
这个问题有没有解决方案或变通方法? - ssasi
一个解决方法是将你与之交互的跨站API/服务器代理到你自己的站点上(例如,让你的服务器将/api/*的请求代理到另一个服务器)。或者,如果你控制另一个服务器,你可以将其托管在你的站点的子域名或相邻域名下,这样Safari就会将其视为“同一站点”。 - undefined

11
问题不在于Safari是否发送cookie,而在于Safari未存储cookie。这与特定的cookie配置组合有关,在localhost上使用此设置可以正常工作。 Set-Cookie: your=cookie; Domain=localhost; Path=/; Expires=Mon, 26 Dec 2022 12:53:02 GMT; HttpOnly; SameSite=Lax 在生产环境下需要使用以下设置: set-cookie: your=cookie; Domain=something.com; Path=/; Expires=Thu, 22 Dec 2022 04:17:44 GMT; HttpOnly; Secure; SameSite=Lax 您需要在两者中都包含Domain,并且对于生产环境需要将Secure设置为(ssl)。你可以使用不同的值SameSite,但Lax适用于我。

2
哇,老兄,我真的很感激我找到了你的答案。你真的救了我的命。我在工作中遇到这个问题已经挣扎了两天,尝试了很多方法,但似乎找不到任何解决方案,直到我找到了你的答案。我很欣赏像你这样的人! :) - Georgi Dimitrov Dimitrov
这件事情折磨了我好几天,而这是唯一有效的解决办法。非常感谢! - Kevin Hoopes
这件事已经让我疯狂了好几天,而这是唯一有效的解决办法。谢谢! - undefined

2

我尝试禁用 MAC OS 中的“防止跨站追踪”选项(即,设置 > Safari > 隐私与安全 > 防止跨站追踪 - 禁用),然后 iframe 开始工作。我知道这不是一个解决方法,但可能是短期内的快速解决方法。


请添加更多细节以扩展您的答案,例如工作代码或文档引用。 - Community

1

自从开始在我们的网站上工作以来,我一直在努力理解cookie。但是最后我终于弄明白了。在我们的服务器上,我们使用Firebase会话在Express应用程序中初始化它们,就像这样:

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,

    })
)

对于我们的iOS应用程序,cookie的设置并不重要,但是对于我们的网站,我们遇到了几个障碍。为了让它在桌面网站浏览器和安卓上正常工作,我们必须将cookie设置为安全和httpOnly。然而,在iOS移动浏览器上,cookie无法设置。问题是因为iOS上的移动浏览器只使用第一方cookie。我不得不为我们的API服务器添加一个CNAME,该服务器是我们网站的子域名,并将API调用定向到该CNAME。然后,在我们的API中必须指定cookie的域(必须明确指定子域允许在cookie中)。这解决了问题。


0
正如其他答案中已经提到的,这似乎是Safari中引入的一种预期行为,它偏离了其他浏览器实现的Web规范。
默认情况下启用的“阻止跨站点追踪”设置会导致所有跨站点的cookie被拒绝,而不管其他浏览器是否接受SameSite=None; Secure
解决方法:
- 如果您控制跨站点API,您可以将其托管在与您的站点具有共同父域的子域或同级域上。似乎只要您的站点和API有一个共同的父域,Safari就会将其视为“同一站点”并允许cookie。我没有支持这一点的文档,但我在Safari 17上进行了测试。
- 请让您站点的服务器代理跨站点API(例如,将/api/*请求代理到其他服务器),从而使API请求成为“同一站点”。如何实现这一点取决于您用于托管站点的解决方案。

0
对于使用Ruby编写的应用程序(特别是Rails,Sinatra或基于Rack的任何应用程序),RailsSameSiteCookie gem可以很好地解决这些问题。该代码几乎是对Chromium讨论中的伪代码进行翻译,而没有脆弱的正则表达式。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接