一、csrf是什么
CSRF(Cross-site request forgery)跨站請求偽造,是一種常見的web安全漏洞,概括地說就是指,攻擊者通過瀏覽器保存的Cookie盜用了你的身份,以你的名義給某個網站發送惡意請求,這些惡意請求包括但不限于發郵件、修改賬戶信息、購買商品、轉賬等等,如果這個網站沒有防御csrf攻擊的話,那么這些惡意請求可能會請求成功,從而泄露了個人的隱私安全和財產安全。怎么樣,聽著夠嚴重吧。
二、csrf的原理
下面我們通過一張圖來簡述下攻擊的原理。
所以,當你在不登出受信網站(即cookie依然有效)的情況下,訪問了惡意網站,那么就有可能發生csrf攻擊。
有人也許會說,我從不訪問惡意網站。這里需要特別注意:這個惡意網站,也許會是一個有其他漏洞的受信網站,惡意攻擊者也可能會以這個網站作為中間網站實施攻擊。
三、了解常見的csrf攻擊
了解了csrf的原理,我們就來看下常見的csrf攻擊的例子。
1.GET類型的CSRF
比如,銀行的轉賬假使使用GET方式來進行(當然現實生活中絕對不是這樣,這里只是舉個例子):
http://bank.com/Transfer.php?accountId=1001&money=1000
那么現在,假使你還沒有登出該銀行網站,又新開了一個瀏覽器tab訪問了惡意網站B,B網站的html中可能會有這樣的代碼:
在惡意網站B加載的時候,也許你什么也沒看到,就是一個空白頁面,但這個空白頁面已經發出了轉賬的請求,結果你的短信來了,告知銀行賬號少了1000塊。
2.POST類型的CSRF
銀行剛剛讓人損失了1000塊,痛定思痛,要把重要的請求都由GET變為POST,于是,前端頁面變成了這樣:
accountId:
Money:
后臺變成了這樣:
if (isset($_REQUEST['accountId'] && isset($_REQUEST['money']))
{
transfer($_REQUEST['toBankId'], $_REQUEST['money']);
}
?>
好了,銀行的代碼變了,惡意網站的代碼還沒變,這時用戶又帶著銀行的cookie訪問了惡意網站,結果又收到了轉賬1000的短信。
這是怎么回事呢?問題出在$_REQUEST數組,應該用$_POST數組的。這也是為什么php代碼中,當使用post提交時,一定要用$_POST的緣故。
那么,我改成了POST數組,這下總能防住了吧!
結果惡意網站也改了代碼:
document.forms[0].submit();
就是一個自動提交的表單,可以再次讓用戶丟1000塊錢。
四、如何防范csrf攻擊
看來如果不做一些事情,這個csrf是防不住的。那作為web開發人員,有哪些防范措施呢?
1.首先,GET方式的csrf攻擊最容易實現,所以,我們的關鍵操作應該只接受POST請求。
2.表單加驗證碼
CSRF攻擊的過程中,往往是在用戶不知情的情況下發送網絡請求的。所以如果使用驗證碼,那么每次操作都需要用戶進行互動,而自動提交的技術通常是猜不到驗證碼的,從而簡單有效的防御了CSRF攻擊。但是驗證碼不能濫用,因為會造成用戶體驗的下降,所以也只在注冊、登錄或者其他重要操作上加驗證碼。
3.檢測Referer
所謂Referer,就是在一個網絡請求頭中的鍵值對,標示著目前的請求是從哪個頁面過來的。服務器通過檢查Referer的值,如果判斷出Referer并非本站頁面,而是一個外部站點的頁面,那么我們就可以判斷出這個請求是非法的。與此同時,我們也就檢測到了一次csrf攻擊。但是,服務器有時候并不能接收Referer值,所以單純地只通過Referer來防御是不太合理的,它因此經常用于csrf的檢測。
4.在重要請求中的每一個URL和所有的表單中添加token
目前主流的做法是使用Token抵御CSRF攻擊。CSRF攻擊成功的條件在于攻擊者能夠預測所有的參數從而構造出合法的請求,所以我們可以加大這個預測的難度,加入一些黑客不能偽造的信息。我們在提交表單時,保持原有參數不變,另外添加一個參數Token,該值可以是隨機并且加密的,當提交表單時,客戶端也同時提交這個token,然后由服務端驗證,驗證通過才是有效的請求,如果不通過就直接拋出403。
考慮下django中是怎么防止csrf攻擊的:
django中使用專門的中間件來防止csrf攻擊,具體的做法是,在需要進行csrf驗證的表單中加入
{% csrf_token %}
這句代碼,當加載表單時,服務端就會利用密鑰以及其他隨機值生成一個token,當提交該表單時,django會修改當前處理的請求,向表單中添加一個隱藏的表單字段:
這個token值一起被提交到了服務端去驗證,從而防止了csrf攻擊,因為如果是其他表單提交的這個請求,這個token是絕對無法驗證通過的。
五、作為普通用戶該怎么辦
作為普通用戶,我們可以盡可能地在訪問某些不確定是否會有惡意攻擊的網站前,把我們的網銀賬戶以及其他賬號登出。
轉載:http://www.yanyaozhen.com/archives/123/