Chrome 80 SameSite Cookie 對 OpenCart 網站的影響

Google 自 Chrome 51 開始,便為瀏覽器的 Cookie 新增加了一個 SameSite 屬性,目的是用來防止 CSRF ,CSRF(Cross-site Request Forgery)是偽造 Cookie 來欺騙網站的一種技巧,讓網站誤判訪客身分,以便藉此執行一些未被允許的操作,在2020年2月發布的 Chrome 80 正式強制推行這項新的 Cookie 安全模式,網站若未宣告 SameSite=None 且使用 HTTPS 連線,則所有 Cookie 相關的請求都會被拒絕。

關於 SameSite 的細部規則,網路上已有不少文章介紹,想了解的網友,請自行 google 搜尋 samesite cookie,此篇文章是要來說明,這樣的改變,對 OpenCart 會造成甚麼影響。

首先先來說明,OpenCart 什麼地方會使用到 cookie ?

cookie 是網站用來記錄資訊於訪客端的瀏覽器,並於每次瀏覽網頁時,傳遞這些資訊以便網站快速了解訪客的暫存狀態。我們以 OpenCart 官方的 demo 網站為例,開啟瀏覽器的檢視功能,就可以看到瀏覽器所記錄的網站 cookie 資訊。

從上圖可以看到,開啟 demo 網站首頁之後,OpenCart 3.x 系統儲存了 3 項資訊在瀏覽器這端,下面 2 項是紀錄幣別及語系,是為了讓 OpenCart 辨識你目前是設定使用哪一種幣別及語系,另一個 OCSESSID 則是記錄你在 OpenCart 網站上的 Session ID 值(在 OpenCart 2.x 是 PHPSESSID)。

什麼是 Session ID 值

OpenCart 系統會利用網站的 Session 功能,紀錄訪客的許多重要資訊在網站主機端,例如已登入的會員帳號資料,您輸入的折價券號碼,進過結帳頁面則會記錄你的地址資料、運送方式、付款方式 …,剛結完帳則會記錄訂單編號等等。記錄這些資訊的目的,是要讓不同的頁面共享這些重要的訪客資訊,以便更容易控管程式的流程,例如進到結帳頁面時,可以先判斷您是否已登入會員帳號,並依據登入會員或非登入會員,顯示不同的結帳頁面。

這些主機端的 Session 資料,每一位訪客都會有自己獨立的一組,OpenCart 系統會幫每一組 Session 資料,建立一個 Session ID 來作為辨識,並且將這個 Session ID 值,透過瀏覽器記錄 Cookie 到你的上網設備(就是上圖的 OCSESSID),當你瀏覽 OpenCart 網站時,即使切換不同頁面,瀏覽器都會送出這些 Cookie 值給 OpenCart,於是 OpenCart 就知道哪一組 Session 是你的,就能載入這些主機端的 Session 資料,知道你是不是已經登入,會員帳號是甚麼等等。

SameSite 機制會造成哪個地方出問題

在 SameSite 機制啟用之前,前面提到的 Session – Cookie 功能,能讓你即使跳轉到其他網站再跳轉回來,例如跳轉到金流公司付款,或跳轉到電子地圖選擇超商門市,再回到 OpenCart 網站,都還是可以透過瀏覽器傳送 cookie 中的 OCSESSID,取得你的 Session ID 進而讀取你的 Session 資料,知道你是哪一位登入會員。

然而在 SameSite 機制啟用之後,或說使用已啟用 SameSite 功能的瀏覽器使用者,在跳轉到金流網站或超取電子地圖網站,再跳轉回 OpenCart 網站時,因為這些跳轉通常是使用 POST 呼叫以便傳遞資訊回 OpenCart 網站,例如傳遞付款交易結果、或是傳遞所選取的超商門市資料,而這個 POST 跳轉剛好符合 SameSite 機制的管制條件,於是,這些跨站跳轉將不會把 cookie 資料傳送到 OpenCart,使得 OpenCart 讀不到你的 OCSESSID,判定你是新的訪客,並建立一組全新的 Session 資料給你,讓你得到一組新的 Session ID,並記錄到你的 Cookie ,覆蓋掉原有的 Session 及 Cookie 資料。

造成的結果就是,從外部網站再跳轉回 OpenCart 網站之後,會因為 OpenCart 無法正確取得您在跳離之前的會員登入資料、剛剛結帳的訂單編號等等,使得 OpenCart 無法接續跳離前的作業,甚至因為資料不足而自動登出會員、出現程式錯誤。

如何修正 SameSite 的問題

SameSite 機制雖然因為疫情的影響,暫時被 Google 展延了,但是這已是無法逃避的問題,所有受影響的網站(應該所有的電商平台都受到影響),都應該盡快修正這個問題,網路上已有不少教學,不過大部分的做法都是修改 Cookie 的 SameSite=None,讓瀏覽器放水網站的 Cookie 管制,但我認為更理想的做法,應該是要符合 Google 推 SameSite 機制的精神,讓 SameSite 機制來提高網站的安全性,至於如何在 Cookie 失效的情形下,讓 Session 資料在跳轉後仍能繼續使用,下一篇再來討論。