Cross Site Request Forgery (CSRF)
Concept
CSRF 就是在不同的 domain 底下卻能夠偽造出「使用者本人發出的 request」,例如A銀行網站存在CSRF攻擊,你在登入的狀況下造訪駭客網站,但該網站隱藏他要發送到A銀行的Request,因瀏覽器機制,你造訪駭客網站而發送到A銀行的請求會幫你把cookie帶上,如此就會像是本人發送的請求。CSRF如何達到攻擊是因為下面兩個因素:
Same Origin Policy 的不足之處
Same Origin Policy雖然可以擋下透過script組成的Origin HTTP Request,例如fetch、ajax等,但透過HTML標籤的HTTP Request卻無法阻擋
瀏覽器處理 Cookies 的方式
如果對同domain對象發送的HTTP Request,瀏覽器會將該domain的Cookies一併送出。
常見的攻擊手法
image tag
通常被用來發HTTP POST/ DELETE / PUT Request。
form submit
需注意form只支援 application/x-www-form-urlencoded、 multipart/form-data 以及 text/plain 這三種 content type
form + iframe submit
駭客替使用者發送一個HTTP Request,不希望使用者點下按鈕馬上發現,通常會將結果頁面輸出到iframe裡,再將iframe用css隱藏起來。
防禦方式
Synchronizer Token Pattern
使用者在發送HTTP Request時,需要將頁面上的某個特徵傳回給Server,也就是CSRF token,token需要符合以下條件
- Server根據這個Session存在一個CSRF token
- 每次進入該頁面,CSRF token都要變,具有時效性
- 要在使用者的登入頁面才能取得CSRF token
- CSRF token必須是不可預測的
Synchronizer Token Pattern常見作法
- Form Submissions
將 CSRF token 放在 form 的隱藏欄位一並送出 - Ajax Requests
將 CSRF token 放在 header 的 meta 欄位,再用 JavaScript 取出送出
Synchronizer Token Pattern缺點
- 頁面若有XSS漏洞那麼CSRF就有可能被駭
- 必須要在Server端存放CSRF token,佔據空間
Submit Cookie
Synchronizer Token Pattern 唯一的不同之處,Server 端不存放 CSRF token.而是將 CSRF token 存在 cookie 裡面,
發送Request到Server時,Server比較頁面提交的CSRF token與Request中的CSRF token
常見作法
- Form Submissions
- Ajax Requests
優點
- 不需要在Server存放CSRF token
缺點
- 頁面若有XSS漏洞,駭客就可以串改Cookie與CSRF token,建議將CSRF token在Cookie儲存時設定屬性為HTTP Only
Triple Submit Cookie
除了與Dounle Submit相同的概念外,多增加在Server與Cookie上存了CSRF token name,所以Request發送到Server,除了比對Cookie 中token value與使用者提交的token value外,需比較Server上的CSRF token name與Cookie中的CSRF token name
缺點
- 頁面若有XSS漏洞,一樣會失效
- 需要在Server維護CSRF token name
Same Site Cookie
原本瀏覽器只判斷 HTTP Request 的「對象」來帶 Cookie ,現在要求要同時判斷 HTTP Request 的「來源」是否跟「對象」為同源,才決定要不要自動帶Cookie。
缺點
- 並非所有瀏覽器都有支援