網站安全🔒 再探同源政策,談 SameSite 設定對 Cookie 的影響與注意事項

Jayden Lin
Oct 27, 2020 · 11 min read

筆者任職於 Yahoo ,線上課程:《經典駭客攻擊教程:給每個人的網站安全入門》粉絲團:《程式猿吃香蕉🍌

(圖片來源:https://blog.heroku.com/chrome-changes-samesite-cookie)

兩年前,我有分享過一篇 Same Origin Policy 同源政策 的文章,討論兩種 Same Origin Policy 對於網站安全的影響,今年以來,由於 SameSite 設定的推出,對於 Cookie 是否會送出的「預設條件」出現變化,對於許多網頁應用程式造成影響,也對網路廣告產業造成衝擊,

本篇文章將會先以同源政策說明 Cookie 的送出條件,再分享 SameSite 的設定,也會介紹幾種情境:iframe 與 form 的使用下,SameSite 設定對 Cookie 的影響許多人常忽略其實 SameSite 設定不只對 Cookie 送出有影響,對其寫入也會有影響,另外,也談到 iOS Safari 實作得不同,最後補充開發時要注意的資訊安全事項

本篇文章包含
✔ Cookie 同源政策是什麼?
✔ SameSite 設定一次看懂
✔ SameSite 常見情境與注意事項:iframe, form, iOS Safari
✔ 結論: 開發時的注意事項

▍Cookie 的同源政策是什麼?

Cookie 的同源政策 (Same Origin Policy) 示意圖

上圖所畫的 Scheme、Domain、Path,是判斷 Cookie 是否跟使用者連上的網站同源的判斷要件(打勾圖示),Port 並不在判斷之列(打叉圖示)

根據 Cookie 的同源政策(Cookie Same Origin Policy),只要連上的網站其 Domain 跟 Path 與 Cookie 一致就會被視為同源.拜訪該網站時,Cookie 就會被送出,而Scheme 的部分,則是要看 Cookie 是否有加入 secure 這個屬性,若是有加上 secure,便會判斷是否是 Https 才會送出詳情可以參考我下面這篇文章

然而在 SameSite 設定被現代瀏覽器廣泛採用之後,Cookie 送出的條件便多了要判斷 SameSite 的部分了

▍SameSite 設定一次看懂

SameSite 主要是針對 Cookie 的一種安全機制,限制 Cookie 僅在第一方情境下使用 (即禁止第三方情況下的使用),實做上是將 SameSite 定義放置於在Http Response Header 中, 屬於 Set-Cookie 的一個屬性。(MDN SameSite)

SameSite 屬性限制了 Cookie 送出的情況,詳細的 SameSite 規格,可以參考 RFC2625bis ,本文介紹三種 SameSite 設定的常見的寫法,了解後可以適用於大部分的情境:

➊ SameSite=Strict

SameSite=Strict 會將 Cookie 限制在『第一方』的情況下使用,舉例來說,當你瀏覽 facebook.com 時,此時 facebook.com 被視為『第一方』,當你登入 facebook.com 時在你的瀏覽器存入『登入用的 Cookie』 ,並限制為 『SameSite=Strict』 ,此時這個 Cookie 被視為第一方 Cookie ,因此你在瀏覽其他 facebook.com頁面時,都被視為在『第一方』的情況下使用,所以Cookie 會被帶上,在你瀏覽時 Cookie 會被送出到 facebook.com,保持登入狀態

但是,在你瀏覽部落格 medium.com 時,此時 medium.com 被視為第一方,先前 facebook.com 存入的 Cookie ,此時被視為 『第三方』了,當你從 medium 點選 facebook 連結連到 facebook 時,此時被視為 『第三方』的 facebook.com Cookie 不會被送出,你連到 facebook 需要重新登入

➋ SameSite=Lax

相較於 SameSite=Strict 的完全禁止『第三方』Cookie使用情境,SameSite=Lax 允許部分 HTML 標籤情況下發送第三方 Cookie。但允許的範圍跟先前只有 Cookie 同源政策時又有些不同。

下表比較『 Lax 』與『以前』(只有同源政策時) ,面對跨來源請求(Cross Request)時,送出 Cookie 的差異可以一目瞭然,以綠色勾的圖示來表示可以送出:

➌ SameSite=None; Secure

SameSite=None 相較於 Lax 又開放了更多第三方 Cookie 的使用情境,例如:iframe、AJAX、Image 。但是以 Chrome 瀏覽器的規定,這項設定必須配合加上 Secure,限制在 Https 下傳輸才可以生效。

在了解了 SameSite 屬性的定義之後,我們來看在幾種情境下的設定

▍SameSite 常見情境與注意事項

以下將探討幾種設定的情境與注意事項:

iframe

iframe 是常見的應用程式情境,例如:Facebook 應用程式 或是 Shopify App 應用程式,都需要串接平台的 SDK ,讓應用程式在 iframe 底下運作

在這個實驗裡,我想強調說明的是:

大部分的人會把 SameSite 的設定著重在『 Cookie的送出』,但其實 SameSite 的設定也會影響到 『 Cookie的寫入

而這個部分是其他文章比較沒有探討到,但卻會造成應用程式出錯的地方,在 iframe 底下,不管是在 Sever 端或是 Client 端的寫入,都會跟 SameSite Cookie 的設定有關係。為了測試,我準備了一個頁面,將分別在 Server 端與 Client 端寫入 Cookies

(測試準備頁面)

(1) 從 Client 端寫入 Cookie 採預設設定,並看 Cookie 是否送出

以下為範例程式碼(使用 React),在 Client 端當頁面 Mount 後,用 JavaScript 寫入 Cookie hello_from_client

實驗結果為,在 iframe 底下,預設 Chrome 會將 Cookie 視為 SameSite=Lax ,並且無法透過 JavaScript 寫入第三方 Cookies

(2) 從 Client 端寫入 Cookie 不使用 SameSite=None, Secure,並看 Cookie 是否送出

以下為範例程式碼(使用 React),在 Client 端當頁面 Mount 後,用 JavaScript 寫入 Cookie hello_from_client

如下圖所示,在 iframe 底下,將 Cookie 設定為 SameSite=Noe, Secure ,便可以透過 JavaScript 寫入第三方 Cookies,並且可以正常傳送到第三方

(SameSite=Noe, Secure ,便可以透過 JavaScript 寫入第三方 Cookies)

(3) 從 Server 端寫入 Cookie 使用 SameSite=Lax,並看 Cookie 是否送出

以下為範例程式碼(使用 Express.js),在頁面載入時,寫入 Cookie hello_from_server

這個實驗是想看說,雖然已知 SameSite=Lax 的 Cookie 無法在 iframe 被送出,但是否能夠從 Server 端寫入呢

經過實驗結果,在 iframe 底下,從 Server 端也無法將使用 SameSite=Lax 的 Cookie 寫入,這點許多使用 iframe 應用程式的網頁要特別注意,若沒有特別設定,從 Server 端也無法寫入 Cookie,並不是只有不能在 Client 被送出的限制

(4) 從 Server 端寫入 Cookie 使用 SameSite=None, Secure,並看 Cookie 是否送出

以下為範例程式碼(使用 Express.js),在頁面載入時,寫入 Cookie hello_from_server

如下圖所示,在 iframe 底下,將 Cookie 設定為 SameSite=Noe, Secure ,便可以透過 Server 端寫入了,並且可以正常傳送到第三方

(Cookie 設定為 SameSite=Noe, Secure ,便可以透過 Server 端寫入)

從以上的實驗我們可以知道,設定 SameSite 除了控制 Cookie 的送出,也會影響 Cookie 的寫入,開發時需要注意

➋ form

另一種常見的情境是表單,很多人以為 SameSite Cookie 之後,就可以不用擔心 CSRF (Cross-Site Request Forgery)了,但其實還是有風險的

這裡我想強調的是一個資訊安全風險,並且常被大家忽略的是:

預設的 SameSite=Lax 是允許 Form做 GET 時,送出 Cookie 的

因此,若是你的 API 採用 GET 做一些會更改狀態的操作,例如:刪除文章或更改帳戶等等那麼你還是有可能將你的應用程式置於危險之中,遭受到 CSRF 攻擊

iOS Safari
許多手機版應用程式會在 iphone 或是 ipad 上面執行,由於 Apple 對於隱私權的重視,Safari 對於 Cookie 的送出更為嚴格,並不依照 RFC 對於 SameSite 的規格實作,甚至有出現 SameSite Cookie 設定為 None 卻依然無法在第三方情境下使用的情況,這點也是開發時需要注意的部分

以下附上兩個討論連結以供參考:

▍結論

從以上文章中可以了解:

  1. 經實驗,SameSite 的設定不只影響 Cookie 的送出,也會影響 Cookie 的寫入,不管是從 Client 端寫入,或是從 Server 端寫入
  2. SameSite=Lax 還是有淺在風險,如果你對應的 API 沒有正確實作,還是有可能造成 Cookie 被送出,遭受 CSRF 攻擊
  3. iphone 或是 ipad 的 Safari 上面對於 Cookie 的送出更為嚴格,有些並不依照 RFC 對於 SameSite 的規格實作,要特別注意

以上為我的分享,希望對大家有幫助對駭客與資訊安全有興趣的朋友,也可以參考我其他文章:

若是喜歡我分享的內容,歡迎幫我按個拍手,可拍 50下,給我一點鼓勵,或是加入我的粉絲團《程式猿吃香蕉🍌,一起分享軟體知識與心得!

程式猿吃香蕉

喜歡將軟體知識以簡單生動的方式講給你聽

程式猿吃香蕉

『來點更營養的軟體知識,吃香蕉吧!』我們是一群軟體開發愛好者,喜歡將軟體知識以簡單生動的方式講給你聽,順口好消化,營養又健康!

Jayden Lin

Written by

Yahoo 擔任 Lead Engineer,負責廣告系統,帶團隊做跨國開發。也是《程式猿吃香蕉》團隊創辦人,喜歡將實用的軟體知識以簡單生動的方式講給大家聽 😄😄😄

程式猿吃香蕉

『來點更營養的軟體知識,吃香蕉吧!』我們是一群軟體開發愛好者,喜歡將軟體知識以簡單生動的方式講給你聽,順口好消化,營養又健康!