CSRF (Cross-Site Request Forgery; 也會簡寫為 XSRF) 攻擊的防禦要另外在伺服器上做,稍微筆記一下原理。
這個攻擊的名稱除了常見的 CSRF / XSRF 之外,也可能被稱為: Sea Surf, Session Riding, Hostile Linking, One-click Attack 等。
簡介
這個攻擊主要是欺騙使用者去觸發「預期之外」的操作 (unwanted actions)。
攻擊目標在於「狀態的改變」,因為伺服器的回復攻擊者不太容易取得,因此偷竊資訊不是主要目標。
可能的攻擊目標類似: 盜買或盜賣、轉帳、更改帳號中的備援電子郵件位址、新增或變更紀錄等。
攻擊時可能會混用一些社交工程的手法,欺騙使用者開啟特製的網頁。
原理
由於瀏覽器在對網站發送 request 時,會附帶上代表使用者身份的資訊,如: session cookies, IP address 等,因此攻擊者有機會製作一個連結或是按鈕,讓使用者誤擊,達到以該使用者身份觸發特定網站上的操作。
一般來說攻擊者不太容易取得操作後的結果,因此主要會是針對「狀態的變更」作為攻擊目標,而非竊取資訊。
搭配 XSS 的話,攻擊強度會倍增,使用者更容易點擊到含有攻擊標籤或程式的頁面,也更容易繞過安全機制。這樣的安全缺失稱為 "Stored CSRF Flaws"。
無效的防禦方式
- 使用祕密的 cookie
-
基本上所有 cookies 都會傳,所以這個方式沒什麼功能。
主流的瀏覽器有個
SameSite
的Set-Cookie
標記,可以指引 cookies 只在來源是該網站時帶入 request 上,但不應該只依賴這個機制。 - 只接受 POST request
-
有很多方法可以騙使用者觸發 POST request 查詢。
- 多階段的交易
-
攻擊者還是有可能完成攻擊。
- URL 改寫
-
這個防禦方式指的是將部份認証用資訊編在 URL 裡面,這樣攻擊者不容易預期操作的 URL 位址,來達到防禦的目的。
利用這個方式可以一定程度迴避 CSRF 攻擊,但將認証資訊嵌在網址中不是好的安全實作方法,並不建議完全依賴這個策略。
- HTTPS
-
完全沒差。
防禦注意事項
- 需完全防禦 XSS
-
XSS 將會使得絕大多數的 CSRF 防禦失效,因為攻擊者將可以使用 XMLHttpRequest 來取得安全機制中的 token 值。
- 要保護的資源
-
一般來說,如果遵照 RFC2616 9.1.1 的建議: 「GET 與 HEAD 為 safe-method,不應該造成 side-effect。」,那麼主要要保護的資源會是
<form>
標籤或 XHR/AJAX 使用的端點。
主要防禦手段
Token-based 的防禦
在 request 中嵌入覆核用的 token 值,可以嵌在:
<form>
的隱藏欄位中 (form POST),或- HTTP 的標頭中 (XHR),或
- URL 中 (GET; 非常不建議)。
不是很建議將 token 嵌在 URL 中,因為很可能會透過瀏覽器的歷史紀錄或是 Refer 而洩漏,反而提供攻擊者機會。
使用 Token-based 防禦有以下注意事項:
- 使用夠強的 Encryption 或 HMAC 函數,建議使用 AES256-GCM (encryption) 或 SHA256/512 (HMAC) 作為加密與簽章函數。
- 需妥善實作 Key rotation 與 Token life-time 的維護。
常見的實作方式:
- Synchronizer Token Pattern
-
將 token 存在 session 中,每次操作後就產生新的 token 值。
這個技巧原本是用來避免重複送出表單,或是防禦重送攻擊。配合
<form>
實作時要注意如果使用者按下上一頁,嵌在<form>
的 token 可能已經無效,需做相關處理。 - Encryption-based Token Pattern
-
將 User ID、時戳、一次性識別碼 (nonce)等資訊使用金鑰加密,作為 token 值。
伺服端在處理後續的操作時在解碼並驗證時戳是否仍有效,透過時戳與 nonce 可以一定程度防禦重送攻擊。
- HMAC Based Token Pattern
-
這個方式類似 Encryption-based token pattern 的作法,但使用 HMAC 取代加密。
投入雜湊函式的值除了 Encryption-based token pattern 中的值之外,建議增加一個每次都不一樣的值,比如說 operation-type 之類的,以避免重送攻擊。相同的目的在 Encryption-based token pattern 中,使用 nonce 來達到增加隨機性的目的。
登入頁面的防護建議特別處理,避免使用者默默地被登入為攻擊者的帳號,以達到竊取使用者線上行為的目的。