簡介
CSRF(Cross-Site Request Forgery)是一種偽裝成已登入使用者、藉此發出非預期請求的攻擊手法。 例如,假設你的應用程式中有一個POST /user/email 可接收 email 變更請求。攻擊者若在另一站點放置能自動送出此 URL 表單的程式碼,使用者可能在不知情下被變更 email。
在 Laravel 13 中,CSRF 保護透過內含於 web 中介軟體群組的機制而預設啟用。
防禦 CSRF 攻擊
Laravel 的PreventRequestForgery 中介軟體以 2 層防禦阻擋 CSRF:
- Origin 驗證(
Sec-Fetch-Site標頭) - Token 驗證(每個 session 的 CSRF token)
Origin 驗證
Laravel 會先檢查Sec-Fetch-Site 判斷請求是否來自相同 Origin。此在 HTTPS 環境下特別有效。
若 Origin 驗證通過,該請求即被允許。若未通過,則會如同以往地執行 CSRF token 驗證。
Origin-only 模式
也可以停用退回至 token 驗證,只以 Origin 驗證進行判斷。403 而非 419。
若要在子網域間允許 same-site 請求,可以設定 allowSameSite。
Token 驗證
Laravel 會為每個 session 生成 CSRF token,可透過csrf_token() 或 session 取得。
web 路由中建立 POST、PUT、PATCH、DELETE 表單時,請務必包含 @csrf。
排除特定 URI
像是 Stripe 的 Webhook 這種來自外部服務的請求,可能需要將特定 URI 排除於 CSRF 保護之外。盡可能將 Webhook 路由放在
web 中介軟體群組之外,並將排除設定降到最少。X-CSRF-TOKEN 標頭
Laravel 不僅會驗證表單的_token,也會檢查 X-CSRF-TOKEN 標頭。
先在 meta 標籤中輸出 token。
X-XSRF-TOKEN 標頭
Laravel 還會傳送加密的XSRF-TOKEN Cookie。Axios 或 Angular 在同源請求時可自動將此值設為 X-XSRF-TOKEN 標頭。
因此在 SPA 或 AJAX 實作中,某些情況下不必手動設定標頭,CSRF 保護就已生效。