CSRF的原理及防禦
簡解:CSRF的原理及防禦
CSRF
Cross-Site Request Forgery,跨站請求偽造。攻擊者通過盜用使用者身份悄悄地
原理
簡單地講,我們在上網的時候,網站會使用cookie來識別使用者身份,【1】每次請求一個資源時,客戶端都會主動附帶cookie給伺服器進行身份認證。【2】如果此時是從第三方頁面(另一個域B)發起對該域(A)的請求,也會附帶上A的cookie。CSRF就是利用這樣的機制實施攻擊的。
【上邊的1和2是為了下邊講清楚,其實它們是一個東西】
- 具體攻擊方式分兩大類:
- 1、 伺服器接受GET方式請求。
- e.g. 1 (針對上邊的【1】)
-
使用者登入了某銀行站點www.bank*.com,使用者可以輸入轉賬id(假設攻擊者id=11)和money通過trasf.php的操作達到轉賬目的。我們構造一個URL:
http://www.bank*.com/trasf.php?id=11&money=10000
==>
這個過程中,由於使用者已經登入了網站,他之後對該網站的請求會附帶自己的身份資訊,也就是cookie,這樣,單擊我們構造的URL之後,就會以使用者的身份向伺服器發出轉賬請求。 - e.g. 2 (針對上邊的【2】)
-
攻擊者搭建一個惡意網站 attack.com,其中有一個頁面X.html有如下程式碼:
<iframe src=http://www.bank*.com/trasf.php?id=11&money=10000>
當用戶登入到銀行www.bank*.com
attack.com/X.html
,完成攻擊。
==>
使用者訪問attack.com/X.html
時,由於是從第三方頁面(attack.com)發起對域(www.bank*.com)的請求,也會附帶上www.bank*.com 的cookie,所以該指令碼帶著cookie執行了,攻擊成功。(<iframe>
會自動執行的,類似的還有<img>
,<script>
等方式)
我們知道,在寫這類涉及敏感資料的表單時,提交方式都會用POST而不是GET,假設上邊的銀行也用了POST方式,但是,我們的CSRF攻擊還是成功了。原因在於,在伺服器接收表單資料時,開發者使用了 $_REQUEST
方法而不是 $_POST
,這導致了本來的POST操作可以用GET方式實現。
- 2、伺服器只接受POST請求。
- e.g.
-
搭建一個攻擊者自己的惡意網站 attack.com,該網站內寫一個頁面,頁面中有一個表單,完成例子1中的那部分表單功能,即
id=11,money=10000,action=www.bank*.com/trasf.php
等,然後有指令碼,指令碼內容為自動將表單提交
。然後讓使用者在登入銀行網站後訪問到該頁面,完成攻擊。
==>
這個攻擊方式也是針對【2】的。
防禦
瞭解了CSRF的原理後,知道其實它完全是以使用者的身份去執行,而應用程式和瀏覽器很難去判斷這是CSRF攻擊還是合法請求。
那麼,防禦方法也就是針對這個來設計了。
主要有以下幾種方法,簡單講一下:
- 使用POST方式替代GET(上邊介紹了)
- 檢驗HTTP Referer
- 使用驗證碼
- 使用token
檢驗HTTP Referer
通過檢查請求頁面的來源,識別從站外發起的請求,也就能防禦CSRF了。
使用驗證碼
每次使用者提交內容時,要求其在表單中填寫驗證碼,提交後對其進行檢測。
驗證碼機制是:伺服器生成一個驗證碼,傳送給客戶端,以圖片形式顯示。然後客戶填寫後,發回伺服器,對比驗證。
使用token
CSRF能成功的一個重要原因是:攻擊者能預知和偽造請求中的關鍵欄位,因此,在請求中放入攻擊者不能偽造的資訊就能防禦CSRF。
token就是在請求中加入一個隨機引數token,伺服器進行驗證。
具體機制我也不懂,資料也沒找到,感覺是像非對稱加密解密那樣的方式。這點等我之後再瞭解清楚,知道的朋友請不吝留言賜教。
Referance (with thanks)
[1]邱永華.XSS跨站指令碼攻擊剖析與防禦[M].北京:人民郵電出版社,2013