事件起因
环境
首先介绍下基本信息:公司的某个业务系统是h.xxx.com,登录走的通过iframe嵌入的网页passport.xxx.com。
本地开发环境下,业务系统只支持http协议,所以对应访问地址为http://h.xxx.com,登录接口始终是https://passport.xxx.com。
这样就是一个跨协议的情况了。
问题
某一天,有同学登录系统后始终提示“你未登录,请先登录B站”,而且并不是所有人有该问题。
经过一系列排查,发现唯一的区别只有Chrome浏览器版本不一致(使用部分其他浏览器也是没有问题的)。
结案
从v88升级到v89后,Chrome浏览器内置的schemeful-same-site规则默认值改为启用,导致跨协议也被认定为跨站(cross-site),cookies无法传递。
临时解决方案:地址栏打开chrome://flags/#schemeful-same-site,将选项设置为Disabled。
在
Chrome 80版本,SameSite的默认值被改为Lax。
Same-Site 的概念
eTLD+1部分一致就可以称之为same-site。
scheme和eTLD+1部分一致则被称为schemeful same-site
下面是一些schemeful same-site的案例:
| Origin A | Origin B | schemeful same-site |
|---|---|---|
| www.example.com:443 | www.evil.com:443 | cross-site: 域名不同 |
| login.example.com:443 | schemeful same-site: 允许子域名不同 | |
| www.example.com:443 | cross-site: 协议不同 | |
| www.example.com:80 | schemeful same-site: 允许端口不同 | |
| www.example.com:443 | schemeful same-site: 完全匹配 | |
| www.example.com | schemeful same-site: 允许端口不同 |
Schemeful Same-Site
Schemeful Same-Site 是 same-site 的进阶版,通过协议+域名两个维度来定义,如果想深入了解下,你可以浏览这篇文章:Understanding 'same-site' and 'same-origin' 。
这意味着 website.example 和website.example 相互之间是跨站(cross-site)的。
如果你的网站已经全部使用HTTPS,那Schemeful Same-Site不会有任何影响,否则应该尽快升级到HTTPS。
如果你的项目同时使用HTTP和HTTPS,那就很有必要了解相关规则,接下来将介绍一些场景以及与之对应的cookie行为。
以前可以通过设置
SameSite=None; Secure来允许跨协议的cookies传输,原作者建议不要使用这个临时解决方案,应该尽快全站部署HTTPS,事实上也确实是这样的,就像前文的登录问题,你永远不知道浏览器给你的下一个“惊喜”是什么。
浏览器相关设置
Chrome和Firefox上提供了schemeful-same-site的配置入口。
Chrome 86开始,修改chrome://flags/#schemeful-same-site选项为Enabled即是启用。Firefox 79开始,打开about:config修改network.cookie.sameSite.schemeful选项为true。
在以前的浏览器更新中,为了防止跨站请求伪造(CSRF)攻击,已经将SameSite=Lax设置为默认项。
然而攻击者还是能通过不安全的HTTP协议篡改cookies,影响到也使用同样cookies的HTTPS页面。
schemeful-same-site也就应运而生。
常见的跨协议场景
导航跳转
之前两个跨协议同域名的页面跳转是允许携带设为SameSite=Strict的cookies。
现在不同协议被认定为跨站(cross-site),所以设为SameSite=Strict的cookies就被阻挡了。
| HTTP → HTTPS | HTTPS → HTTP | |
|---|---|---|
| SameSite=Strict | ⛔ Blocked | ⛔ Blocked |
| SameSite=Lax | ✅ Allowed | ✅ Allowed |
| SameSite=None;Secure | ✅ Allowed | ⛔ Blocked |
加载子资源
主流浏览器都会阻止 active mixed content(主动型混合内容) ,如
scripts、iframe。Chrome和Firefox浏览器正在尝试升级或阻止passive mixed content(被动型混合内容)。
子资源(subresources)包括图片,iframes 以及 XHR、Fetch请求
之前如果一个页面加载了跨协议的资源,他们之间是可以共享设为SameSite=Strict、SameSite=Lax的cookies。
然而现在两者统统被浏览器阻止,无法传输共享。
另外即使HTTPS能够加载HTTP资源,所有的cookies还是会被阻止。
| HTTP → HTTPS | HTTPS → HTTP | |
|---|---|---|
| SameSite=Strict | ⛔ Blocked | ⛔ Blocked |
| SameSite=Lax | ⛔ Blocked | ⛔ Blocked |
| SameSite=None;Secure | ✅ Allowed | ⛔ Blocked |
POST表单提交
以前跨协议的POST请求是可以携带设为SameSite=Lax或SameSite=Strict的cookies。
现在只有设置为SameSite=None的cookies可以在表单请求时被发送。
| HTTP → HTTPS | HTTPS → HTTP | |
|---|---|---|
| SameSite=Strict | ⛔ Blocked | ⛔ Blocked |
| SameSite=Lax | ⛔ Blocked | ⛔ Blocked |
| SameSite=None;Secure | ✅ Allowed | ⛔ Blocked |
如何在网页上测试
Chrome和Firefox上的开发者工具都已经支持相关配置,并且会在控制台给出提示。
Chrome 86版本开始,DevTools->Issue显示关于Schemeful Same-Site的高亮提示。
Navigation issues:
- "Migrate entirely to HTTPS to continue having cookies sent on same-site requests"—A warning that the cookie will be blocked in a future version of Chrome.
- "Migrate entirely to HTTPS to have cookies sent on same-site requests"—A warning that the cookie has been blocked.
子资源加载issues:
- "Migrate entirely to HTTPS to continue having cookies sent to same-site subresources" or "Migrate entirely to HTTPS to continue allowing cookies to be set by same-site subresources"—Warnings that the cookie will be blocked in a future version of Chrome.
- "Migrate entirely to HTTPS to have cookies sent to same-site subresources" or "Migrate entirely to HTTPS to allow cookies to be set by same-site subresources"—Warnings that the cookie has been blocked. The latter warning can also appear when POSTing a form.
详情可以阅读 Testing and Debugging Tips for Schemeful Same-Site。
Firefox 79版本开始,network.cookie.sameSite.schemeful设置为true后,控制台也会呈现相关信息:
- "Cookie cookie_name will be soon treated as cross-site cookie against site.example/ because the scheme does not match."
- "Cookie cookie_name has been treated as cross-site against site.example/ because the scheme does not match."
FAQ
我的网页已经使用HTTPS,为什么还会看到issues?
很可能是网页内的一些链接或资源还是指向不安全的地址。
其中一个解决办法就是使用 HTTP Strict-Transport-Security (HSTS) + includeSubDomain。
使用 HSTS + includeSubDomain 方案之后,即便你的页面里还存在不安全的链接,浏览器会自动替换安全的协议访问。
如果我无法升级到HTTPS
可以调整SameSite的设置,放宽限制。
- 只有
SameSite=Strict的cookies被阻止时,你可以调整为SameSite=Lax - 设置为
Strict或Lax的cookies均被阻止,同时cookies是发送到安全URL的,把设置为None后就可以生效。
如果cookies没有设置SameSite属性?
没有SameSite属性的cookies,会被当成SameSite=Lax处理。
WebSockets
Same-site:
wss://connection fromhttps://ws://connection fromhttp://
Cross-site:
wss://connection fromhttp://ws://connection fromhttps://
本文主要内容来自:Schemeful Same-Site
关注公众号:湖中剑,找到更多关于我的内容。