跨站請求偽造 (CSRF) 防禦
跨站請求偽造 (CSRF) 可以透過 SameSite Cookie 和反 CSRF 令牌進行防禦。
問題
CSRF 是一種攻擊型別,攻擊者會透過可信使用者向網站傳送未經授權的命令。由於它們繼承了使用者的 Cookie(因此也繼承了會話資訊),因此它們看起來是有效的命令。CSRF 攻擊可能如下所示
<!-- Attempt to delete a user's account -->
<img src="https://accounts.example.org/management/delete?confirm=true" />
當用戶訪問包含上述 HTML 的頁面時,瀏覽器將嘗試向源 URL 發出 GET 請求。如果使用者已登入,瀏覽器將提供其會話 Cookie,並且帳戶刪除嘗試將成功。
解決方案
SameSite Cookie
SameSite Cookie 允許您指定您希望瀏覽器僅在響應來自 Cookie 源站點的請求時才傳送 Cookie。例如,這將導致 CSRF 攻擊失敗,因為惡意命令不會附帶 Cookie,因此無法以使用者身份進行身份驗證。可用的值是
嚴格-
導致瀏覽器僅在響應來自 Cookie 源站點的請求時才傳送 Cookie。
寬鬆-
與
嚴格相似,只是瀏覽器還會在使用者導航到 Cookie 的源站點時傳送 Cookie(即使使用者來自不同的站點)。 無-
指定在源請求和跨站點請求中都發送 Cookie。
您應該為您的網站設定儘可能強大的 SameSite 級別,以使其仍然有效。理想情況下,除非您確實需要,否則永遠不要設定 無。請記住,如果未指定標頭,則 寬鬆 是預設值。
反 CSRF 令牌
反 CSRF 令牌透過要求在所有破壞性更改中都存在一個秘密、唯一且不可預測的令牌來防止 CSRF 攻擊。這些令牌可以為整個使用者會話設定,定期輪換,或者為每個請求唯一建立。
建議您為允許破壞性更改(如帳戶刪除)的網站使用這兩種策略。對於其他網站,反 CSRF 令牌可能不是必需的,儘管仍然建議將 SameSite 設定為非 無 值,以幫助保護使用者的 隱私。
大多數應用程式框架都內建了 CSRF 令牌化功能,以簡化實施。請務必選擇一個具有此功能的框架,不要試圖重新造輪子。
示例
實施反 CSRF 令牌以及 SameSite=嚴格
在帳戶刪除表單中包含一個秘密的反 CSRF 令牌
<input
type="hidden"
name="csrftoken"
value="1df93e1eafa42012f9a8aff062eeb1db0380b" />
在伺服器端,設定反 CSRF Cookie(JavaScript 必須將其傳送為 X 標頭;它無法跨源執行)
Set-Cookie: CSRFTOKEN=1df93e1eafa42012f9a8aff062eeb1db0380b; Path=/; Secure; SameSite=Strict
回到客戶端,使用 JavaScript 將 CSRF 令牌作為 X 標頭新增到 XMLHttpRequest
const token = readCookie(CSRFTOKEN); // read the cookie
httpRequest.setRequestHeader("X-CSRF-Token", token); // add it as an X-CSRF-Token header