事件起因
環境
首先介紹下基本信息:公司的某個業務系統是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 |
|---|---|---|
| https://www.example.com:443 | https://www.evil.com:443 | cross-site: 域名不同 |
| https://login.example.com:443 | schemeful same-site: 允許子域名不同 | |
| http://www.example.com:443 | cross-site: 協議不同 | |
| https://www.example.com:80 | schemeful same-site: 允許端口不同 | |
| https://www.example.com:443 | schemeful same-site: 完全匹配 | |
| https://www.example.com | schemeful same-site: 允許端口不同 |
Schemeful Same-Site
Schemeful Same-Site 是 same-site 的進階版,通過協議+域名兩個維度來定義,如果想深入瞭解下,你可以瀏覽這篇文章:Understanding 'same-site' and 'same-origin' 。
這意味着 http://website.example 和https://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 http://site.example/ because the scheme does not match."
- "Cookie cookie_name has been treated as cross-site against http://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
關注公眾號:湖中劍,找到更多關於我的內容。