先辨認回應內容,再選擇標頭

商店可快取公開標誌、商品照片及有版本號的程式檔案,但訂單頁應另作判斷。先問回應是否含有特定登入顧客的地址、訂單紀錄或已存偏好。HTTP 分為私有快取,例如瀏覽器,以及代理伺服器或 CDN 等共享快取;RFC 9111 說明各自可如何儲存及重用回應。MDN 指出,要求中有 cookie 不會自動令回應變成私有;不應進入共享快取的個人化內容需要明確政策。先列出路線及實際回應內容,不要對整個網站一律套用同一標頭。

每條路線都應記下屬於哪一類:人人相同的公開內容、可留在單一使用者瀏覽器的個人化內容,或敏感到不應被 HTTP 快取刻意保存的內容。範圍要包括 HTML、JSON 端點、可下載文件、重新導向,以及可能回傳個人細節的錯誤頁。公開產品目錄與登入後的「我的訂單」即使用同一版面,也需不同快取規則。若帳戶頁由公開外殼及私人 API 資料組成,兩個回應應分開處理。除了最初的網頁文件,亦要查看背景要求,因為真正載有資料的回應可能不在可見頁面的標頭。

分清 private、no-cache 與 no-store 的作用

沒有附加條件的 `private` 指示共享快取不可儲存回應,私有快取則可在其他規則容許下保存。`no-cache` 常被誤會:它容許儲存,但重用前必須向伺服器驗證。`no-store` 則指示私有及共享 HTTP 快取都不要儲存。三者不是同一句話的不同寫法。個人化頁若可以留在顧客自己的瀏覽器,但每次重用前需核對伺服器,`private, no-cache` 可作起點。若回應含特別敏感的工作階段或帳戶資料,OWASP 的工作階段指引建議使用 `no-store`。真正選用前,仍須按資料及顧客旅程判斷並測試。

不要過度承諾。RFC 9111 明確指出,`no-store` 本身不是充分可靠的私隱機制;惡意或受入侵的快取未必遵守。它管理的是 HTTP 快取,不會控制所有瀏覽器儲存空間,更不能阻止截圖。反過來,所有公開頁都使用 `no-store`,會放棄有用的快取與瀏覽器導覽行為。MDN 亦提到它對前進/返回快取等功能的成本。私隱仍需存取控制、傳輸保護、工作階段管理及謹慎的應用程式設計。快取標頭只處理其中一種重用風險,不能決定誰本來有權讀取訂單。

檢查 CDN 及中介快取規則

應用程式可能送出謹慎標頭,但 CDN 規則卻把某個路徑下所有成功回應都快取。要檢查邊緣節點設定、快取鍵及登入路線的例外。RFC 9111 對帶有 Authorization 標頭的要求設有共享快取限制,除非回應指示容許;但以 cookie 登入的流量不能因為不屬該條件便被視為安全。個人化回應要明確標記,並在實際部署的 CDN 測試。特別檢查邊緣規則會否覆蓋來源的 `Cache-Control`、按副檔名或狀態碼快取,或忽略使用者差異。OWASP 的網頁快取指引指出跨客戶資料曝光及 CDN 覆蓋設定等實際風險。

實用測試可用兩個資料明顯不同的受控顧客帳戶。帳戶 A 先要求訂單頁,帳戶 B 再透過同一邊緣位置要求相同路徑或等效帳戶路線;B 絕不能收到 A 的私人頁面內容或標頭。快取已暖機、部署後及登出後都要重做。分別查看來源伺服器與 CDN 的回應標頭,包括 `Cache-Control`、快取狀態及 `Vary` 欄位。單一次 `MISS` 不能證明安全,因為後續要求可能得到不同結果;公開資源出現 `HIT` 也不一定有問題。真正要問的是該快取版本是否適合當前使用者和路線。

以登出情境作重點驗收

想像顧客在家庭共用電腦查看地址及訂單紀錄,登出後按「返回」。伺服器必須拒絕沒有有效工作階段的新私人要求,但瀏覽器先前儲存的頁面仍可能在導覽時出現。OWASP 警告工作階段結束後,敏感資料可能仍可從瀏覽器快取讀到,並建議載有敏感工作階段資料的回應使用 `no-store`。先決定哪些頁面需要較強政策,再按實際瀏覽器行為驗收,不要假設所有瀏覽器反應完全一樣。共用裝置的使用者也應明白:登出可阻止之後的授權要求,但未必會抹去裝置上已顯示的一切痕跡。

驗收路線要清楚:以 A 登入,打開私人頁,登出,按「返回」,重新整理,再打開已儲存網址;在另一瀏覽器及同一裝置的第二名使用者重做。逐步記錄畫面顯示甚麼,以及網絡回應有沒有 A 的資料。舊畫面快照、未授權的新網絡回應,以及伺服器錯誤地批准存取,是三種需要不同修正的問題。敏感下載文件亦要檢查,因為 PDF 可能經另一條路線送出,標頭未必相同。顧客可理解的目標是:共用電腦使用者未經重新驗證,不能取得新的帳戶資料;高敏感內容也不會被 HTTP 快取刻意保留。

網站改動後維持政策有效

可建立簡短回應矩陣:公開靜態檔、公開動態頁、個人頁及高敏感帳戶回應。每一類寫明預定可快取的對象、新鮮度規則及測試方法。新增路線、更改 CDN 或遷移登入方式時,都按矩陣重檢。若網站使用 service worker,須另外查看其 Cache API 規則;OWASP 指出 HTTP 快取標頭不會自動支配程式主動存入該 API 的項目。若英文及繁體中文走不同路線或頁面外殼,兩者都要測,縱然標頭語義不因語言而變。最有力證據是部署路線的實際回應及跨帳戶測試結果,而不是設定註解聲稱政策已生效。

這項決定不是比賽誰加最多 `no-store`。公開而有版本號的資源應按自己的版本快取政策處理;個人回應要防止跨使用者洩漏;敏感回應可能需要更強的瀏覽器儲存限制。兩個外觀相似的網址,合理地可以使用不同指示。若測試發現舊私人回應早已存入快取,之後的新回應改為 `no-store` 未必能清除舊項目;MDN 特別提醒這個限制。要為受影響路線設計修復並重新測試。真正有用的成果,是一套有文件及實測支持的安全重用分界,讓網站擴展後仍能維持。

發布檢查要包括失敗回應,不能只看成功頁面。帳戶端點的錯誤訊息可能含有訂單編號或聯絡資料,邊緣節點又可能按寬鬆的狀態碼規則快取。來源伺服器暫時無法使用、訂單不屬於登入者,以及工作階段過期時,都要查看回應內容與標頭。測試應使用假資料,避免把真顧客資料留在測試擷取檔。若故障期間快取需要提供公開後備頁,必須確定內容真的公開,沒有嵌入前一位使用者狀態。這也是檢查語言版本的時機:兩種語言的公開頁可各自安全快取,但其中一版加入個人問候後,分類便會改變。分類依據應是實際送出的位元組,而非路線名稱。

團隊應為新功能訂明例外審核程序。開發人員若在原本公開的產品目錄加入個人化推薦,即使網址和版面不變,頁面的快取分類也可能改變。發布檢查要問:哪些輸入會改變回應、快取鍵有否反映這些輸入,以及回應是否本來就容許多人共用。答案未清楚前,應先避免共享快取,待設計審核。帳戶頁初始 HTML 沒有姓名,也不能因此宣稱安全;若稍後由 API 載入私人資料,就要檢查該 API 回應及瀏覽器的儲存路徑。故障時亦應預先定義來源伺服器無法回應,快取可提供甚麼:過時的公開產品描述,與過時的帳戶結餘或訂單狀態,後果完全不同。把選定規則和理由記在路線負責人的文件旁,日後改動才有依據。

進行前先確認

  • 個人化 HTML、API、文件及錯誤回應是否與公開資源分開分類?
  • 來源及 CDN 回應在兩個測試帳戶之間是否依預定政策運作?
  • 登出後,使用者能否透過返回、重新整理或已存網址取得新的私人資料?

資料來源及延伸閱讀