對於跨站偽造請求(CSRF)的理解和總結
本文轉自:對於跨站偽造請求(CSRF)的理解和總結
CSRF攻擊 CSRF攻擊是什麼CSRF
是跨站請求偽造的縮寫,也被稱為XSRF
, 是一種挾制使用者在當前已登入的Web應用程式上執行非本意的操作的攻擊方法。
跟跨網站指令碼(XSS)相比,XSS利用的是使用者對指定網站的信任,CSRF利用的是網站對使用者網頁瀏覽器的信任。
因為CSRF攻擊利用的是衝著瀏覽器分不清發起請求是不是真正的使用者本人。,也就是說,簡單的身份驗證只能保證請求發自某個使用者的瀏覽器,卻不能保證請求本身是使用者自願發出的。
最簡單的CSRF攻擊
- 使用者Alice登入和訪問某銀行網站A,保留
cookie
- Alice被某些資訊誘導訪問危險網站B。
- 危險網站B上有一個
<img>
標籤:<img src="http://www.examplebank.com/account=Alice&amount=1000&payfor=Badman" >
- 這個標籤的src不指向一張圖片,而是一個http請求,這個請求向銀行要求將Alice的1000元轉給Badman,由於Alice的瀏覽器上有
cookie
,這樣瀏覽器發出的這個請求就能得到響應執行。 - 這樣Alice的錢就被偷了。
進階攻擊
危險網站可以偽造一個表單並隱藏,並在自己網站的onload
事件中,觸發這個表單的提交事件,就可以改GET攻擊為POST攻擊
我們要防範它,先要知道它的目標,然後設法保護這些目標。
我們要明白,僅僅靠發起CSRF攻擊的話,黑客只能藉助受害者的cookie
騙取伺服器的信任,但是黑客並不能憑藉拿到cookie
,也看不到cookie
的內容。另外,對於伺服器返回的結果,由於瀏覽器同源策略的限制,黑客也無法進行解析。
這就告訴我們,我們要保護的物件是那些可以直接產生資料改變的服務,而對於讀取資料的服務,則不需要進行CSRF
的保護。
而保護的關鍵,是在請求中放入黑客所不能偽造的資訊。
最基本的手段:涉及敏感操作的請求改為POST請求
這個方法的確可以防範一些CSRF
攻擊,但是對於進階攻擊就無能為力了——POST
所以這個方法不夠安全。只能提高攻擊的門檻。
一般手段
使用者操作限制——驗證碼機制
方法:新增驗證碼來識別是不是使用者主動去發起這個請求,由於一定強度的驗證碼機器無法識別,因此危險網站不能偽造一個完整的請求。
優點:簡單粗暴,低成本,可靠,能防範99.99%的攻擊者。
缺點:對使用者不友好。
請求來源限制——驗證 HTTP Referer 欄位
方法:在HTTP
請求頭中有一個欄位叫Referer
,它記錄了請求的來源地址。 伺服器需要做的是驗證這個來源地址是否合法,如果是來自一些不受信任的網站,則拒絕響應。
優點:零成本,簡單易實現。
缺點:由於這個方法嚴重依賴瀏覽器自身,因此安全性全看瀏覽器。
- 相容性不好:每個瀏覽器對於
Referer
的具體實現可能有差別。 - 並不一定可靠:在一些古老的垃圾瀏覽器中,
Referer
可以被篡改。 - 對使用者不友好:
Referer
值會記錄下使用者的訪問來源,有些使用者認為這樣會侵犯到他們自己的隱私權。因此有些使用者可能會開啟瀏覽器防止跟蹤功能,不提供Referer
,從而導致正常使用者請求被拒絕。
額外驗證機制——token的使用
方法:使用token
來代替驗證碼驗證。由於黑客並不能拿到和看到cookie
裡的內容,所以無法偽造一個完整的請求。基本思路如下:
- 伺服器隨機產生
token
(比如把cookie
hash化生成),存在session
中,放在cookie
中或者以ajax
的形式交給前端。 - 前端發請求的時候,解析
cookie
中的token
,放到請求url
裡或者請求頭中。 - 伺服器驗證
token
,由於黑客無法得到或者偽造token
,所以能防範csrf
更進一步的加強手段(不需要session):
- 伺服器隨機產生
token
,然後以token
為金鑰雜湊生成一段密文 - 把
token
和密文都隨cookie
交給前端 - 前端發起請求時把密文和
token
都交給後端 - 後端對
token
和密文進行正向雜湊驗證,看token
能不能生成同樣的密文 - 這樣即使黑客拿到了
token
也無法拿到密文。
優點:
- 安全性:極大地提高了破解成本(當然還是有辦法破解),但是99%的攻擊者看到雜湊的時候就已經望而生畏了。
- 易用性:非常容易實現。
- 友好性:對使用者來說十分友好。
缺點:
- 效能擔憂:需要
hash
計算,增加效能上的成本 cookie
臃腫:更加依賴網路的情況- 並不絕對安全:
- 一些論壇之類支援使用者自己發表內容,由於系統也會在這個地址後面加上
token
,這樣黑客可以在自己的網站上得到這個token
,並馬上就可以發動CSRF攻擊。(進一步加強法可以防範,或者驗證連結是否是鏈到自己本站的,是就在後面新增token
,如果是通向外網則不加) - 其他攻擊方式如XSS攻擊能拿到
cookie
和token
,當然這不在本文的討論範圍之內。
- 一些論壇之類支援使用者自己發表內容,由於系統也會在這個地址後面加上
- 對於POST請求,難以將
token
附在請求中。(可以通過框架和庫解決)
曲線救國——在HTTP頭中自定義屬性並驗證
方法:這種方法也是使用token並進行驗證,和上一種方法不同的是把它放到HTTP頭中自定義的屬性裡。
優點:
- 這樣解決了上種方法在請求中加入 token 的不便
- 通過 XMLHttpRequest 請求的地址不會被記錄到瀏覽器的位址列,安全性較高
缺點:
- 侷限性非常大:XMLHttpRequest請求通常用於Ajax,並非所有的請求都適合用這個類來發起,而且通過該類請求得到的頁面不能被瀏覽器所記錄下,造成不便。
- 對於舊網站,要把所有請求都改為XMLHttpRequest請求,這樣幾乎是要重寫整個網站,這代價無疑是不能接受的。
總結
因為CSRF攻擊利用的是衝著瀏覽器分不清發起請求是不是真正的使用者本人,所以防範的關鍵在於在請求中放入黑客所不能偽造的資訊。從而防止黑客偽造一個完整的請求欺騙伺服器。