詳解 Cookie 新增的 SameParty 屬性
各大主流瀏覽器正在逐步禁用 三方Cookie ,之前筆者也在下面這篇文章中分析了全面禁用 三方Cookie 后對我們的網站帶來的一些影響:
當瀏覽器全面禁用三方 Cookie
但是一個公司或組織往往在不同業務下會有多個不同的域名,例如 taobao.com、tianmao.com,所以很多正常的業務場景也許要借助 三方Cookie 來實現(比如 單點登錄和 consent管理),直接禁用后可能會給我們的業務帶來很大影響,而且之前一直以來都沒有很好的解決方案,這也是 Chrome 禁用 三方Cookie 進展非常緩慢的原因。
在 第一方Cookie 和 第三方Cookie 被區別對待的情況下,Chrome 新推出了一個 First-Party Sets 策略,它可以允許由同一實體擁有的不同關域名都被視為第一方。
這意味著我們可以標記打算在同一方上下文共享 Cookie 的不同域名,目的是在防止第三方跨站點跟蹤和仍然保持正常的業務場景下之間找到平衡。
目前 First-Party Sets 策略還沒有正式在穩定版推出,還在試用階段。
一方和三方 Cookie 的區別
可能很多小伙伴對 三方Cookie 的概念還比較模糊,我們先來回顧一下:
Cookie 本質上不區分第一方或第三方,它取決于包含 Cookie 的當前上下文。我們還用之前的老例子:
如果是你正常的正在逛著天貓,天貓會把你的信息寫入一些 Cookie 到 .tmall.com 這個域下,然而打開控制臺你會看到,并不是所有 Cookie 都是 .tmall.com 這個域下的,里面還有很多其他域下的 Cookie ,這些所有非當前域下的 Cookie 都屬于第三方 Cookie,雖然你可能從來沒訪問過這些域,但是他們已經悄悄的通過這些第三方 Cookie來標識你的信息,然后把你的個人信息發送過去了。
而 .tmall.com 這個域下的 Cookie 都屬于第一方 Cookie,那么為什么還需要第三方 Cookie 呢?再打開 taobao.com,你會發現你已經不需要再登錄了,因為淘寶、天貓都屬于阿里旗下的產品,阿里為他們提供統一的登錄服務,同時,你的登錄信息也會存到這個統一登錄服務的域下,所以存到這個域下的 Cookie 就成了三方 Cookie。
SameSite 的問題
Chrome 在之前的版本為 Cookie 新增了一個 SameSite 屬性 來限制三方 Cookie 的訪問,在 Chrome 80 版本后 SameSite 的默認值被設定為 SameSite=Lax。
在 Strict 模式下,將阻止所有三方 Cookie 攜帶,這種設置基本可以阻止所有 CSRF 攻擊,然而,它的友好性太差,即使是普通的 GET 請求它也不允許通過。
在 Lax 模式下只會阻止在使用危險 HTTP 方法進行請求攜帶的三方 Cookie,例如 POST 方式。同時,使用 JavaScript 腳本發起的請求也無法攜帶三方 Cookie。
但是,試用上面兩種模式,我們上面提到的一些正常的需求場景就無法實現了,對于這種 Cookie ,我們現在一般會手動設置 SameSite=None 。
這意味著這種 Cookie 又失去了跨站點請求偽造 (CSRF) 保護,例如在 evil.site 發送一個 me.site 的請求,也會帶上我們的 Cookie。
First-Party Sets 策略
在上面正常的業務場景中,所有不同的域名基本上都來自同一個組織或企業,我們希望在同一個運營主體下不同域名的 Cookie 也能共享。
First-Party Sets 可以定義跨站點上下文仍然是 first-party 的情況。Cookie 可以包含在第一方集合中,也可以排除在第三方上下文中。
First-Party Sets 提出了一種明確定義在同一主體下擁有和運營的多個站點關系的方法。比如 .tmall.com、taobao.com 都可以被定義為同一主體運營 。
這個策略來源于瀏覽器的隱私沙提案中對身份進行分區以防止跨站點跟蹤的概念,在站點之間劃定界限,限制對可用于識別用戶的任何信息的訪問。
瀏覽器的默認行為是對同一站點進行分區,上面這個新的策略意味著分區被可以開放為多個站點。
First-Party Sets 策略的一個重要部分是確保跨瀏覽器的政策防止濫用或誤用。例如,First-Party Sets 策略不得在不相關的站點之間交換用戶信息,或對不屬于同一實體的站點進行分組。
所以單點登錄這種場景可能是不能用這種方式解決了,因為這個場景屬于交換用戶信息,目前怎么界定哪些信息是用戶信息官方還沒有明確的描述,所以這個地方筆者也不是很確定。
W3C 目前正在討論新的 First-Party Sets 的配置和驗證,其中一個考慮的選項是由獨立實體而非瀏覽器公司處理驗證。
目前 First-Party Sets 已經確定的原則如下:
- First-Party Sets 中的域必須由同一組織擁有和運營。
- 所有域名應該作為一個組被用戶識別。
- 所有域名應該共享一個共同的隱私政策。
如何定義 First-Party Sets
每一個需要用到 First-Party Sets 策略的域名都應該把一個 JSON 配置托管在 /.well-known/first-party-set 路由下。
例如 conardli.top 的配置應該托管在 https://conardli.top/.well-known/first-party-set 下:
- {
- "owner": "conardli.top",
- "version": 1,
- "members": ["conardli.com", "conardli.cn"]
- }
另外 conardli.com、 conardli.cn 兩個域名均需要增加所有者的配置:
- {
- "owner": "conardli.top"
- }
First-Party Sets 還有一些限制:
- 一個集合可能只有一個所有者。
- 一個成員只能屬于一個集合,不能重疊或混合。
- 域名列表不要過大。
SameParty 屬性
好了,上面介紹了一大堆,終于回到本文的主題 Cookie SameParty 屬性了,這個屬性就是為了配合 First-Party Sets 使用的。
所有開啟了 First-Party Sets 域名下需要共享的 Cookie 都需要增加 SameParty 屬性,例如,如果我在 conardli.top 下設置了下面的 Cookie :
- Set-Cookie: name=lishiqi; Secure; SameSite=Lax; SameParty
這時我在 conardli.cn 下發送 conardli.top 域名的請求,Cookie 也可以被攜帶了,但是如果我在另外一個網站,例如 eval.site 下發送這個請求, Cookie 就不會被攜帶。
在 SameParty 被廣泛支持之前,你可以把它和 SameSite 屬性一起定義來確保 Cookie 的行為降級,另外還有一些額外的要求:
- SameParty Cookie 必須包含 Secure.
- SameParty Cookie 不得包含 SameSite=Strict.
如何試用?
在瀏覽器禁用三方 Cookie 后,這個新的提案應該會被大范圍的使用,現在可以先試用起來啦!
你可以在下面兩個地方參與提案的討論:
- First-Party Sets 策略討論:https://github.com/privacycg/first-party-sets
- SameParty 屬性討論:https://github.com/cfredric/sameparty
現在提案還在試用階段,你可以試用 --use-first-party-set 這個命令啟動 Chrome ,就可以進行試用啦!
比如,在示例站 https://fps-member1.glitch.me/ 添加如下配置:
- --use-first-party-set=https://fps-member1.glitch.me,https://fps-member2.glitch.me,https://fps-member3.glitch.me
參考
- https://www.chromestatus.com/feature/5280634094223360
- https://github.com/cfredric/sameparty
- https://developer.chrome.com/blog/first-party-sets-sameparty/