跨站請求偽造 (CSRF) 防禦

跨站請求偽造 (CSRF) 可以透過 SameSite Cookie 和反 CSRF 令牌進行防禦。

問題

CSRF 是一種攻擊型別,攻擊者會透過可信使用者向網站傳送未經授權的命令。由於它們繼承了使用者的 Cookie(因此也繼承了會話資訊),因此它們看起來是有效的命令。CSRF 攻擊可能如下所示

html
<!-- Attempt to delete a user's account -->
<img src="https://accounts.example.org/management/delete?confirm=true" />

當用戶訪問包含上述 HTML 的頁面時,瀏覽器將嘗試向源 URL 發出 GET 請求。如果使用者已登入,瀏覽器將提供其會話 Cookie,並且帳戶刪除嘗試將成功。

解決方案

有多種 CSRF 緩解策略可用。最常見且最透明的 CSRF 緩解方法是 SameSite Cookie 和反 CSRF 令牌。

注意:跨站指令碼 (XSS) 漏洞可能會克服您實施的任何 CSRF 緩解技術。確保同時針對這兩種攻擊型別強化您的網站。可以使用 內容安全策略 (CSP) 等功能來防止 XSS。

SameSite Cookie

SameSite Cookie 允許您指定您希望瀏覽器僅在響應來自 Cookie 源站點的請求時才傳送 Cookie。例如,這將導致 CSRF 攻擊失敗,因為惡意命令不會附帶 Cookie,因此無法以使用者身份進行身份驗證。可用的值是

嚴格

導致瀏覽器僅在響應來自 Cookie 源站點的請求時才傳送 Cookie。

寬鬆

嚴格 相似,只是瀏覽器還會在使用者導航到 Cookie 的源站點時傳送 Cookie(即使使用者來自不同的站點)。

指定在源請求和跨站點請求中都發送 Cookie。

您應該為您的網站設定儘可能強大的 SameSite 級別,以使其仍然有效。理想情況下,除非您確實需要,否則永遠不要設定 。請記住,如果未指定標頭,則 寬鬆 是預設值。

反 CSRF 令牌

反 CSRF 令牌透過要求在所有破壞性更改中都存在一個秘密、唯一且不可預測的令牌來防止 CSRF 攻擊。這些令牌可以為整個使用者會話設定,定期輪換,或者為每個請求唯一建立。

建議您為允許破壞性更改(如帳戶刪除)的網站使用這兩種策略。對於其他網站,反 CSRF 令牌可能不是必需的,儘管仍然建議將 SameSite 設定為非 值,以幫助保護使用者的 隱私

大多數應用程式框架都內建了 CSRF 令牌化功能,以簡化實施。請務必選擇一個具有此功能的框架,不要試圖重新造輪子。

示例

實施反 CSRF 令牌以及 SameSite=嚴格

在帳戶刪除表單中包含一個秘密的反 CSRF 令牌

html
<input
  type="hidden"
  name="csrftoken"
  value="1df93e1eafa42012f9a8aff062eeb1db0380b" />

在伺服器端,設定反 CSRF Cookie(JavaScript 必須將其傳送為 X 標頭;它無法跨源執行)

http
Set-Cookie: CSRFTOKEN=1df93e1eafa42012f9a8aff062eeb1db0380b; Path=/; Secure; SameSite=Strict

回到客戶端,使用 JavaScript 將 CSRF 令牌作為 X 標頭新增到 XMLHttpRequest

js
const token = readCookie(CSRFTOKEN); // read the cookie
httpRequest.setRequestHeader("X-CSRF-Token", token); // add it as an X-CSRF-Token header

另請參閱