基本概念
當一個使用者已經登入並且在當前域名下儲存了相關的 Cookie(如身份驗證資訊等),如果開啟一個偽造的 HTML 頁面,並且該頁面中的 <form>
元素的 action 屬性包含完整的 API 請求全路徑指向同一域名,瀏覽器在傳送該表單請求時會自動攜帶該域名下儲存的 Cookie
。
同一域名下的所有請求(包括表單提交、XHR、Fetch 請求等)都會自動附帶瀏覽器中儲存的 Cookie
資訊,除非使用了 SameSite、HttpOnly 等安全設定來限制特定的 Cookie
行為。
攻擊過程
- 使用者登入可信站點:使用者登入一個網站後,網站通常會在使用者瀏覽器中設定一個認證 cookie,用於維持使用者的會話。
- 攻擊者偽造請求:攻擊者建立一個惡意網頁(或者一段惡意程式碼),該頁面向使用者已登入的網站傳送請求。這些請求可能是透過
<form>
表單提交、圖片連結、AJAX 請求等方式偽造的。 - 瀏覽器自動攜帶 cookie:由於請求的目標域名與使用者登入的網站相同,瀏覽器會自動附帶之前的認證 cookie(如 session cookie),伺服器將其視為合法使用者的請求。
- 伺服器執行請求:如果網站沒有足夠的防護措施,伺服器會執行該請求,認為這是由合法使用者發出的,從而造成惡意操作,比如更改賬戶資訊、進行轉賬等。
假設一個使用者登入了銀行網站 bank.com
,並且銀行網站在使用者的瀏覽器中設定了認證 Cookie。攻擊者傳送給使用者一個包含以下內容的惡意 HTML 頁面:
<form action="https://bank.com/transfer" method="POST">
<input type="hidden" name="to_account" value="attacker_account">
<input type="hidden" name="amount" value="1000">
<input type="submit" value="Submit">
</form>
使用者一旦開啟這個頁面,表單會自動提交,並攜帶瀏覽器中的認證 Cookie。銀行網站接收到請求後,認為這是使用者自願的轉賬操作,從而執行了轉賬。
防禦 CSRF
- CSRF Token: 在表單中加入一個唯一的 Token(令牌),伺服器在接收到請求時驗證這個 Token 是否與使用者會話中的一致。由於攻擊者無法獲取合法的 Token,因此偽造的請求會被拒絕。
- SameSite Cookie: 將 Cookie 的
SameSite
屬性設定為Lax
或Strict
,限制 Cookie 在跨站請求中的傳遞。這樣,攻擊者無法在跨站請求中利用使用者的 Cookie。 - 檢查 Referer 和 Origin 頭: 伺服器端可以檢查請求的
Referer
或Origin
頭,確保請求是來自同一站點,而不是第三方站點。