Skip to main content

簡介

CSRF(Cross-Site Request Forgery)是一種偽裝成已登入使用者、藉此發出非預期請求的攻擊手法。 例如,假設你的應用程式中有一個 POST /user/email 可接收 email 變更請求。攻擊者若在另一站點放置能自動送出此 URL 表單的程式碼,使用者可能在不知情下被變更 email。 在 Laravel 13 中,CSRF 保護透過內含於 web 中介軟體群組的機制而預設啟用。

防禦 CSRF 攻擊

Laravel 的 PreventRequestForgery 中介軟體以 2 層防禦阻擋 CSRF:
  1. Origin 驗證Sec-Fetch-Site 標頭)
  2. Token 驗證(每個 session 的 CSRF token)
會先檢查 Origin,若無法判斷或失敗時再退回到 token 驗證。

Origin 驗證

Laravel 會先檢查 Sec-Fetch-Site 判斷請求是否來自相同 Origin。此在 HTTPS 環境下特別有效。 若 Origin 驗證通過,該請求即被允許。若未通過,則會如同以往地執行 CSRF token 驗證。
Sec-Fetch-Site 是為 HTTPS 連線設計的。在 HTTP 環境中 Origin 驗證無法運作,主要防禦仍會是 token 驗證。

Origin-only 模式

也可以停用退回至 token 驗證,只以 Origin 驗證進行判斷。
在 Origin-only 模式下,Origin 驗證失敗的請求會回傳 403 而非 419 若要在子網域間允許 same-site 請求,可以設定 allowSameSite

Token 驗證

Laravel 會為每個 session 生成 CSRF token,可透過 csrf_token() 或 session 取得。
web 路由中建立 POSTPUTPATCHDELETE 表單時,請務必包含 @csrf

排除特定 URI

像是 Stripe 的 Webhook 這種來自外部服務的請求,可能需要將特定 URI 排除於 CSRF 保護之外。
盡可能將 Webhook 路由放在 web 中介軟體群組之外,並將排除設定降到最少。

X-CSRF-TOKEN 標頭

Laravel 不僅會驗證表單的 _token,也會檢查 X-CSRF-TOKEN 標頭。 先在 meta 標籤中輸出 token。
再將該值加入 AJAX 請求標頭。

X-XSRF-TOKEN 標頭

Laravel 還會傳送加密的 XSRF-TOKEN Cookie。Axios 或 Angular 在同源請求時可自動將此值設為 X-XSRF-TOKEN 標頭。 因此在 SPA 或 AJAX 實作中,某些情況下不必手動設定標頭,CSRF 保護就已生效。

SPA 中的注意事項

當 SPA 以 Laravel 作為 API 後端時,需先取得 CSRF Cookie,才能送出登入請求。
詳細請參閱 Sanctum
最後修改於 2026年8月2日