為什麼要在意 Cookie/Session 安全?
Session 代表使用者登入狀態;誰拿到 session,就等於變成那位使用者。
攻擊者常見手法:竊聽(未加密傳輸)、XSS 讀取/注入、CSRF 偽造請求、Session Fixation(固定會話)、Referrer 洩漏等。
Set-Cookie 的三個關鍵屬性
功能:Cookie 僅會在 HTTPS 連線時送出,阻擋明文竊聽。
注意:請求依然可能被截取內容(若站點有其他漏洞),Secure 只是傳輸保護,仍需搭配 HTTPS 全站與其他安全措施。
功能:瀏覽器 禁止 JavaScript 讀寫此 Cookie,降低 XSS 之後被 document.cookie 直接偷走的風險。
注意:XSS 仍能發送請求(因為瀏覽器會自動帶 Cookie),所以還需要 CSP、輸入處理、框架的 XSS 防護。
Strict:幾乎所有跨站導引都不帶 Cookie;安全最高,但可能影響外部導流回來後的登入狀態。
Lax(現代瀏覽器預設):跨站 GET 導航(例如使用者點連結)可帶 Cookie,其它跨站情境不帶;常用、折衷。
None:允許跨站都帶 Cookie,但必須搭配 Secure;適用 SSO、跨網域子系統、第三方嵌入。
結論:後台/高風險操作建議 SameSite=Strict;一般網站常用 Lax;跨網域 App/SSO 才用 None; Secure,並補上 CSRF Token 與正確 CORS。
其他重要屬性與技巧
路徑/網域範圍
Path:盡量縮小(例如 /app/),避免多餘路徑也帶上 Cookie。
Domain:不要隨便設成 .example.com,除非所有子網域都可信;不設 Domain(預設 Host-only)更安全。
前綴:
__Secure-:必須 Secure 且在 HTTPS 設定。
__Host-:更嚴格,必須 Secure、不可設 Domain、Path=/。可防止子網域覆蓋 Cookie,適合放 session。
範例:Set-Cookie: __Host-session=...; Path=/; Secure; HttpOnly; SameSite=Lax
期限/大小
Max-Age / Expires:短一點較安全(例如數十分鐘~數小時)+滑動續期策略。
大小限制:每顆約 4KB、每網域數十顆上限——請不要塞太多資訊進 Cookie。
為什麼「不要把 session token 放在 URL」?
URL 會進入 瀏覽器歷史、伺服器日誌、Proxy 日誌、分析工具、錯誤追蹤。
會透過 Referrer 洩漏給下一個站點(雖然可用 Referrer-Policy 緩解,但根治方式是不放 URL)。
使用者分享/截圖 URL 時也會外洩。
正解:只放在 Cookie(或授權標頭),不要放 URL。
常見攻擊與對策
攻擊 說明 核心對策
竊聽 攻擊者在開放網路偷看封包 全站 HTTPS + Secure
XSS 注入惡意腳本竊取/濫用 Session HttpOnly、CSP、輸入/輸出安全、框架防 XSS
CSRF 偽造使用者跨站發請求 SameSite(Lax/Strict)、CSRF Token、檢查 Origin/Referer
Session Fixation 在登入前把 Session ID 固定,登入後沿用 登入/提權後重新產生 Session ID
子網域覆蓋 惡意子網域設置同名 Cookie 覆蓋 用 __Host- 前綴、不要設定 Domain
伺服器端 Session 管理最佳實務
強隨機 Session ID
128 位元以上的不可預測隨機值(CSPRNG)。不要用可被推測的序列或短值。
登入/提權後「重新產生」Session(Regeneration)
防止 Session Fixation:使用者登入或權限升級時,換一個新的 Session ID,舊的立即失效。
短存活 + 滑動續期
例如 30 分鐘閒置就失效;每次活躍請求可延長。
伺服器端可撤銷
Session 存於伺服器(例如 Redis、資料庫),可即時 登出/吊銷;避免把狀態完全放在無法撤銷的 JWT。
裝置/風險檢查(可選)
記錄最近 IP、UA 指紋;異常時要求再驗證或踢出舊會話(注意隱私與誤傷)。
Cookie vs. JWT(存哪裡?)
Cookie + 伺服器 Session(建議新手/一般網站)
易撤銷、配合 HttpOnly/Secure/SameSite 很安全。
JWT(無狀態)
適合微服務,但撤銷困難,需短效存活 + 黑名單/旋轉策略。
不要存 JWT 在 localStorage(易被 XSS 取走);若必用 JWT,也建議放在 HttpOnly Cookie,並用 CSRF 對策。
CSRF:SameSite 之外還要做什麼?
對 跨站可帶 Cookie 的情境(SameSite=None 或 Lax 被瀏覽器特例繞過),務必:
CSRF Token(同步 token 或 double-submit)
檢查 Origin / Referer(HTTPS 嚴格比對)
僅允許指定來源的 CORS(Access-Control-Allow-Origin 絕對不要用 * 搭配 credentials)