CSRF 防護
規則
- 在所有 Cookie 上設定
SameSite=Lax — 這會預設阻擋大多數 CSRF 攻擊
- 對高度敏感的操作(帳戶刪除、密碼變更)使用
SameSite=Strict
- 為自訂 API 實作雙重提交 Cookie 模式:將 CSRF Token 放在 Cookie 和請求標頭中
- 在所有執行狀態變更操作的 HTML 表單中包含 CSRF Token
- 驗證狀態變更請求的
Origin 和 Referer 標頭,作為深度防禦
- Next.js Server Actions 和 SvelteKit form actions 會自動處理 CSRF — 請使用它們
- 對於 SPA:在自訂標頭 (
X-CSRF-Token) 中發送 CSRF Token — 瀏覽器預設會阻擋跨來源的自訂標頭
import crypto from "crypto";
function generateCsrfToken(res) {
const token = crypto.randomBytes(32).toString("hex");
res.cookie("csrf_token", token, { httpOnly: false, sameSite: "strict", secure: true });
return token;
}
function verifyCsrf(req) {
const cookieToken = req.cookies.csrf_token;
const headerToken = req.headers["x-csrf-token"];
if (!cookieToken || cookieToken !== headerToken) {
throw new Error("CSRF 驗證失敗");
}
}
避免
- 僅依賴 Cookie-based 認證而沒有 CSRF 防護 — 任何網站都可以向你的端點提交表單
- 永不輪換的 CSRF Token — 一個 Token 洩漏就會危及所有未來請求
- 讓 GET 請求變更狀態 — CSRF 防護只對 POST/PUT/DELETE 有效,因為 GET 請求會繞過 SameSite=Lax
- 因為「它只是個 API」而停用 CSRF 防護 — 只要涉及 Cookie,CSRF 就適用