1. 程式人生 > 實用技巧 >對於跨站偽造請求(CSRF)的理解和總結

對於跨站偽造請求(CSRF)的理解和總結

本文轉自:對於跨站偽造請求(CSRF)的理解和總結

CSRF攻擊 CSRF攻擊是什麼

CSRF是跨站請求偽造的縮寫,也被稱為XSRF, 是一種挾制使用者在當前已登入的Web應用程式上執行非本意的操作的攻擊方法。
跟跨網站指令碼(XSS)相比,XSS利用的是使用者對指定網站的信任,CSRF利用的是網站對使用者網頁瀏覽器的信任。
因為CSRF攻擊利用的是衝著瀏覽器分不清發起請求是不是真正的使用者本人。,也就是說,簡單的身份驗證只能保證請求發自某個使用者的瀏覽器,卻不能保證請求本身是使用者自願發出的。

CSRF攻擊基本原理

最簡單的CSRF攻擊

  1. 使用者Alice登入和訪問某銀行網站A,保留cookie
  2. Alice被某些資訊誘導訪問危險網站B。
  3. 危險網站B上有一個<img>標籤:<img src="http://www.examplebank.com/account=Alice&amount=1000&payfor=Badman" >
  4. 這個標籤的src不指向一張圖片,而是一個http請求,這個請求向銀行要求將Alice的1000元轉給Badman,由於Alice的瀏覽器上有cookie,這樣瀏覽器發出的這個請求就能得到響應執行。
  5. 這樣Alice的錢就被偷了。

進階攻擊

危險網站可以偽造一個表單並隱藏,並在自己網站的onload事件中,觸發這個表單的提交事件,就可以改GET攻擊為POST攻擊

CSRF攻擊的物件與防範思路

我們要防範它,先要知道它的目標,然後設法保護這些目標。
我們要明白,僅僅靠發起CSRF攻擊的話,黑客只能藉助受害者的cookie騙取伺服器的信任,但是黑客並不能憑藉拿到cookie,也看不到cookie的內容。另外,對於伺服器返回的結果,由於瀏覽器同源策略的限制,黑客也無法進行解析。
這就告訴我們,我們要保護的物件是那些可以直接產生資料改變的服務,而對於讀取資料的服務,則不需要進行CSRF的保護。
而保護的關鍵,是在請求中放入黑客所不能偽造的資訊。

防範手段

最基本的手段:涉及敏感操作的請求改為POST請求

這個方法的確可以防範一些CSRF攻擊,但是對於進階攻擊就無能為力了——POST

請求一樣可以偽造。
所以這個方法不夠安全。只能提高攻擊的門檻。

一般手段

使用者操作限制——驗證碼機制

方法:新增驗證碼來識別是不是使用者主動去發起這個請求,由於一定強度的驗證碼機器無法識別,因此危險網站不能偽造一個完整的請求。
優點:簡單粗暴,低成本,可靠,能防範99.99%的攻擊者。
缺點:對使用者不友好。

請求來源限制——驗證 HTTP Referer 欄位

方法:在HTTP請求頭中有一個欄位叫Referer,它記錄了請求的來源地址。 伺服器需要做的是驗證這個來源地址是否合法,如果是來自一些不受信任的網站,則拒絕響應。
優點:零成本,簡單易實現。
缺點:由於這個方法嚴重依賴瀏覽器自身,因此安全性全看瀏覽器。

  1. 相容性不好:每個瀏覽器對於Referer的具體實現可能有差別。
  2. 並不一定可靠:在一些古老的垃圾瀏覽器中,Referer可以被篡改。
  3. 對使用者不友好:Referer值會記錄下使用者的訪問來源,有些使用者認為這樣會侵犯到他們自己的隱私權。因此有些使用者可能會開啟瀏覽器防止跟蹤功能,不提供Referer,從而導致正常使用者請求被拒絕。

額外驗證機制——token的使用

方法:使用token來代替驗證碼驗證。由於黑客並不能拿到和看到cookie裡的內容,所以無法偽造一個完整的請求。基本思路如下:

  1. 伺服器隨機產生token(比如把cookiehash化生成),存在session中,放在cookie中或者以ajax的形式交給前端。
  2. 前端發請求的時候,解析cookie中的token,放到請求url裡或者請求頭中。
  3. 伺服器驗證token,由於黑客無法得到或者偽造token,所以能防範csrf

更進一步的加強手段(不需要session):

  1. 伺服器隨機產生token,然後以token為金鑰雜湊生成一段密文
  2. token和密文都隨cookie交給前端
  3. 前端發起請求時把密文和token都交給後端
  4. 後端對token和密文進行正向雜湊驗證,看token能不能生成同樣的密文
  5. 這樣即使黑客拿到了token也無法拿到密文。

優點:

  1. 安全性:極大地提高了破解成本(當然還是有辦法破解),但是99%的攻擊者看到雜湊的時候就已經望而生畏了。
  2. 易用性:非常容易實現。
  3. 友好性:對使用者來說十分友好。

缺點:

  1. 效能擔憂:需要hash計算,增加效能上的成本
  2. cookie臃腫:更加依賴網路的情況
  3. 並不絕對安全:
    1. 一些論壇之類支援使用者自己發表內容,由於系統也會在這個地址後面加上token,這樣黑客可以在自己的網站上得到這個token,並馬上就可以發動CSRF攻擊。(進一步加強法可以防範,或者驗證連結是否是鏈到自己本站的,是就在後面新增token,如果是通向外網則不加)
    2. 其他攻擊方式如XSS攻擊能拿到cookietoken,當然這不在本文的討論範圍之內。
  4. 對於POST請求,難以將token附在請求中。(可以通過框架和庫解決)

曲線救國——在HTTP頭中自定義屬性並驗證

方法:這種方法也是使用token並進行驗證,和上一種方法不同的是把它放到HTTP頭中自定義的屬性裡。

優點:

  1. 這樣解決了上種方法在請求中加入 token 的不便
  2. 通過 XMLHttpRequest 請求的地址不會被記錄到瀏覽器的位址列,安全性較高

缺點:

  1. 侷限性非常大:XMLHttpRequest請求通常用於Ajax,並非所有的請求都適合用這個類來發起,而且通過該類請求得到的頁面不能被瀏覽器所記錄下,造成不便。
  2. 對於舊網站,要把所有請求都改為XMLHttpRequest請求,這樣幾乎是要重寫整個網站,這代價無疑是不能接受的。

總結

因為CSRF攻擊利用的是衝著瀏覽器分不清發起請求是不是真正的使用者本人,所以防範的關鍵在於在請求中放入黑客所不能偽造的資訊。從而防止黑客偽造一個完整的請求欺騙伺服器。