SameSite 那些事

《Web 安全漏洞之 CSRF》中咱們瞭解到,CSRF 的本質其實是利用了 Cookie 會自動在請求中攜帶的特性,誘使用戶在第三方站點發起請求的行爲。除了文中說的一些解決方式以外,標準還專門爲 Cookie 增長了 SameSite 屬性,用來規避該問題。Chrome 於 2015 年 6 月支持了該屬性,Firefox 和 Safari 緊隨其後也增長了支持。SameSite 屬性有如下幾個值:html

  • SameSite=None:不管是否跨站都會發送 Cookie
  • SameSite=Lax:容許部分第三方請求攜帶 Cookie
  • SameSite=Strict:僅容許同站請求攜帶 Cookie,即當前網頁 URL 與請求目標 URL 徹底一致

該屬性適合全部在網頁下的請求,包括但不限於網頁中的 JS 腳本、圖片、iframe、接口等頁面內的請求。能夠看到 None 是最寬鬆的,和以前的行爲無異。而 LaxStrict 都針對跨站的狀況下作了限制。其中 Strict 最爲嚴格,不容許任何跨站狀況下攜帶該 Cookie。Lax 則相對寬鬆一點,容許了一些顯式跳轉後的 GET 行爲攜帶。如下是一個帶有 SameSite 屬性的標準 Cookie 響應示例:前端

Set-Cookie: name=lizheming; SameSite=None; Secure

須要注意的是,瀏覽器作了僅針對 HTTPS 域名才支持 SameSite=None 配置。因此若是你要設置 SameSite=None 的話,則必須還要攜帶 Secure 屬性才行。git

Same Site

Same Site 直譯過來就是同站,它和咱們以前說的同域 Same Origin 是不一樣的。二者的區別主要在於判斷的標準是不同的。一個 URL 主要有如下幾個部分組成:github

能夠看到同域的判斷比較嚴格,須要 protocol, hostname, port 三部分徹底一致。相對而言,Cookie 中的同站判斷就比較寬鬆,主要是根據 Mozilla 維護的公共後綴表(Pulic Suffix List)使用有效頂級域名(eTLD)+1的規則查找獲得的一級域名是否相同來判斷是不是同站請求。web

例如 .org 是在 PSL 中記錄的有效頂級域名,imnerd.org 則是一級域名。因此 https://blog.imnerd.orghttps://www.imnerd.org 是同站域名。而 .github.io 也是在 PSL 中記錄的有效頂級域名,因此 https://lizheming.github.iohttps://blog.github.io 獲得的一級域名是不同的,他們兩個是跨域請求。chrome

在相似 GitHub/GitLab Pages, Netlify, Vercel 這種提供子域名給用戶建站的第三方服務中,eTLD 的這種同站判斷特性每每很是有用。經過將本來是一級域的域名添加到 eTLD 列表中,從而讓瀏覽器認爲配有用戶名的完整域名纔是一級域,有效解決了不一樣用戶站點的 Cookie 共享的問題。跨域

eTLD

eTLD 的全稱是 effective Top-Level Domain,它與咱們往常理解的 Top-Level Domain 頂級域名有所區別。eTLD 記錄在以前提到的 PSL 文件中。而 TLD 也有一個記錄的列表,那就是 Root Zone Database。RZD 中記錄了全部的根域列表,其中不乏一些奇奇怪怪五花八門的後綴。瀏覽器

eTLD 的出現主要是爲了解決 .com.cn, .com.hk, .co.jp 這種看起來像是一級域名的但其實須要做爲頂級域名存在的場景。這裏還能夠分享一個有趣的事情,2020年5月份出現了一塊兒阿里雲全部 ac.cn 後綴網站解析所有掛掉的事件。緣由就是 ac.cn 是中科院申請在冊的 eTLD 域名。而阿里雲的檢測域名備案的腳本不瞭解規範,沒有使用 PSL 列表去查找一級域名,而是使用了.分割的形式去查找的。最終全部 *.ac.cn 的域名因爲 ac.cn 這個域名沒有進行備案致使解析所有掛掉。而咱們如今知道 ac.cn 這個域名是 eTLD 域名,它確定是沒法備案的。安全

Schemeful Same Site

在 Chrome 86/Firefox 79 中,瀏覽器增長了一個 Schemeful Same Site 的選項,將協議也增長到了 Same Site 的判斷規則中。可是並非徹底的不等判斷,能夠理解是否有 SSL 的區別。例如 http://https:// 跨站,但 wss://https:// 則是同站,ws://http:/ 也算是同站。cookie

Chrome 能夠瀏覽器輸入 chrome://flags/#schemeful-same-site 找到配置並開啓。

Lax

咱們知道互聯網廣告經過在固定域 Cookie 下標記用戶 ID,記錄用戶的行爲從何達到精準推薦的目的。隨着全球隱私問題的整治,同時也是爲了更好的規避 CSRF 問題,在 Chrome 80 中瀏覽器將默認的 SameSite 規則從 SameSite=None 修改成 SameSite=Lax。設置成 SameSite=Lax 以後頁面內全部跨站狀況下的資源請求都不會攜帶 Cookie。因爲不會爲跨站請求攜帶 Cookie,因此 CSRF 的跨站攻擊也無從談起,廣告商也沒法固定用戶的 ID 來記錄行爲。

對用戶來講這確定是一件好事。可是對咱們技術同窗來講,這無疑是上游給咱們設置的一個障礙。由於業務也確實會存在着多個域名的狀況,而且須要在這些域名中進行 Cookie 傳遞。例如多站點使用 SSO 登陸、接入統一的驗證碼服務、前端和服務端接口屬於兩個域名等等狀況,都會由於這個修改受到影響。

這個修改影響面普遍,須要網站維護者花大量的時間去修改適配。而 Chrome 80 於 2020 年 2 月發佈後全球就開始面臨新冠疫情的影響。考慮到疫情問題後續的版本里又暫時先回退了這個特性(相關連接),最終是在 Chrome 86 進行了全量操做。

針對由於這次特性受到影響的網站,能夠選擇如下一些適配辦法:

  1. 使用 JWT 等其它非 Cookie 的通訊方式
  2. 爲 Cookie 增長 SameSite=None;Secure 屬性配置
  3. 全部的跨域接口增長 Nginx 代理,使其和頁面保持同域

每一種方法都須要一些取捨。第一種更換 Cookie 的方式改形成本很是高,特別是在有外部業務對接的狀況下基本不可能。第三種方式經過將跨域變爲同域的轉發方式可能會帶來線上流量的成倍增長,也是須要考慮的因素。第二種設置成 None 看起來是比較簡單的辦法,不過也有着諸多的限制。

  1. SameSite=None;Secure 因爲僅支持 HTTPS 頁面,因此若是有 HTTP 的場景須要考慮跳轉至 HTTPS 或者選擇其餘方案;
  2. 因爲 SameSite 屬性是後來才加入的,一些老瀏覽器(其實就是 IE)會忽略帶有這些屬性的 Cookie,因此須要同時下發未配置 SameSite 屬性和配置 SameSite 屬性的兩條 Set-Cookie 響應頭,這樣支持和不支持的會各取所需;
  3. 在 Safari 的某些版本中會將 SamteSite=None 等同於 SameSite=Strict 因此部分 Safari 場景須要特殊處理不進行下發(相關連接);

綜上使用代理轉發的方式是我比較推薦的方式,除了不那麼綠色以外兼容問題處理仍是不錯的。

SameParty

SameSite=None 斷了咱們跨站傳遞 Cookie 的念想,但實際業務上確實有這種場景。例如 Google 本身就有很是多的域名,這些域名若是都須要共享登陸 Cookie 的話可能就會很是困難了。針對這種某個實體擁有多個域名須要共享 Cookie 的狀況,就有人(那其實就是 Google 的同窗)提出了 [SameParty](
https://github.com/cfredric/s... 的概念。

該提案提出了 SameParty 新的 Cookie 屬性,當標記了這個屬性的 Cookie 能夠在同一個主域下進行共享。那如何定義不一樣的域名屬於同一主域呢?主要是依賴了另一個特性 first-party-set 第一方集合。它規定在每一個域名下的該 URL /.well-known/first-party-set 能夠返回一個第一方域名的配置文件。在這個文件中你能夠定義當前域名從屬於哪一個第一方域名,該第一方域名下有哪些成員域名等配置。

固然使用固定 URL 會產生額外的請求,對頁面的響應形成影響。也能夠直接使用 Sec-First-Party-Set 響應頭直接指定歸屬的第一方域名。

不過 W3C TAG 小組已經強烈拒絕了該提案(來源)。W3C 認爲該提案從新定義了網站沙箱的邊界,帶來的影響可能不只僅只是 Cookie 共享這麼簡單,包括麥克風、攝像頭、地理信息等隱私設置都須要去從新評估影響。

同時該提案可能會和用戶的預期不一致,若是 Google 和 Youtube 被定義成第一方網站進行共享的話,那 Google 就能很輕鬆的獲取到用戶在 Youtube 上的行爲,可能用戶並不想要這樣。

W3C TAG 小組全稱是 Technical Architecture Group,即 W3C 技術架構組。TAG 是 W3C 專一於 Web 架構管理的特殊小組。其使命是爲 Web 架構的設計原則尋求共識,且在必要時梳理並澄清這些設計原則,幫助協調 W3C 內部及外部跨越不一樣技術的架構定義與研發工做。基本能夠認爲它是 Web 基礎規範定義的小組。另外萬維網之父 Tim Berners-Lee 也在 TAG 小組中。

不過 W3C 說的有理沒理,都阻擋不了 Chrome 去實現這個功能。在 Chrome 89 中已經增長了 SameParty 的相關邏輯,只是目前沒有默認開啓。目前在 DevTools 中是能夠看到 Cookie 的 SameParty 屬性列的。Edge 因爲使用了 Chromium 也在同版本支持了該功能。只掌管了規範,沒有掌管實現,當某一方瀏覽器實現了「霸權」的狀況下,W3C 的處境就變得尷尬了起來。

FLoC

SameSite 除了影響單實體多域名共享 Cookie 的狀況,最大的問題其實就是互聯網廣告獲取用戶行爲了。因爲廣告掛載頁面和廣告不在同域,因此廣告沒法得到用於標記用戶 ID 從而對用戶行爲進行聚類。爲了解決這個問題,有人(其實也是 Google 的同窗)提出了 Federated Learning of Cohorts 同盟學習隊列提案。

有別於以前使用 Cookie ID 標記直接將用戶行爲數據傳遞到廣告商網站處理的方式。它提出了 document.interestCohort() 這個新的 API,將用戶的行爲在本地轉換成了不帶我的隱私的關鍵詞,既規避了用戶隱私問題,同時又解決了廣告的精準投放問題。

不過這看似美好的東西卻遭到了各大網站和瀏覽器的強力抵制,bravVivaldiduckduckgoGitHub 以及 Edge,Firefox,Safari(來源)都紛紛發表了拒絕支持的觀點和行動。

社區主要的擔憂點在於,新的特性的增長可能會增長特徵值爲隱私嗅探提供了更廣闊的入口。並且經過該 API 能獲取到以前礙於權限沒法程序獲取的用戶瀏覽數據。目前 Chrome 已經支持了這個功能,不過須要開啓 Flag 才能支持。amIFLoCed 是一個用來檢測你的瀏覽器是否開啓了 FLoC 追蹤特性的網站,可使用它檢測你的瀏覽器是否應用該特性。

後記

爲了解決 CSRF 問題,Chrome 強推了 SameSite=Lax 做爲默認配置。隨之而來的,不只是全球開發者的配合修改,還形成了已有場景的沒法知足。而爲了知足現有場景,又提出了 SamePartyFLoC 兩個方案。這種行爲不知可否成爲瀏覽器的內卷行爲?

SameSite 屬性自己是沒有什麼問題的,但我的認爲它應該是一種 CSRF 問題的選擇方案,瀏覽器將其默認修改爲 SameSite=Lax 就有點難受了。大部分企業項目裏都已經採用其餘 CSRF 防範方式規避了該問題,而 Lax 配置又存在着兼容性問題,不能讓咱們徹底免顧 CSRF 之憂。

隨着全球隱私問題的白熱化,不知道還有什麼新的提案搞出來須要咱們全球開發者爲其買單。

參考資料:

相關文章
相關標籤/搜索
每日一句
    每一个你不满意的现在,都有一个你没有努力的曾经。