跨站請求偽造(英語:Cross-site request forgery),也被稱為 one-click attack 或者 session riding,通??s寫為 CSRF 或者 XSRF, 是一種挾制用戶在當前已登錄的Web應用程序上執行非本意的操作的攻擊方法。
和跨網站腳本(XSS)相比,XSS 利用的是用戶對指定網站的信任,CSRF 利用的是網站對用戶網頁瀏覽器的信任。
攻擊細節
跨站請求攻擊,簡單地說,是攻擊者通過一些技術手段欺騙用戶的瀏覽器去訪問一個自己曾經認證過的網站并執行一些操作(如發郵件,發消息,甚至財產操作如轉賬和購買商品)。由于瀏覽器曾經認證過,所以被訪問的網站會認為是真正的用戶操作而去執行。這利用了web中用戶身份驗證的一個漏洞:簡單的身份驗證只能保證請求發自某個用戶的瀏覽器,卻不能保證請求本身是用戶自愿發出的。
CSRF可以做什么?
你也可以這么理解CSRF攻擊:攻擊者盜用了你的身份,以你的名義發送惡意請求。CSRF能夠做的事情包括:以你名義發送郵件,發消息,盜取你的賬號,甚至于購買商品,虛擬貨幣轉賬......造成的問題包括:個人隱私泄露以及財產安全。
CSRF原理
下面一張圖簡單闡述了CSRF的原理
CSRF的原理
從上圖可以看出,要完成一次CSRF攻擊,受害者必須依次完成以下兩個步驟:
- 登錄受信任網站A,并在本地生成Cookie。
- 在不登出A的情況下,訪問危險網站B。
- 看到這里,你也許會問:“如果我不滿足以上兩個條件中的一個,我就不會受到CSRF攻擊”。是滴,確實如此,但是你不能保證以下情況不會發生:
- 你不能保證你登錄了一個網站之后,不再打開一個tab頁面并訪問其它的網站(黃網)。
- 你不能保證你關閉瀏覽器之后,你本地的Cookie立刻過期,你上次的會話已經結束。
- 上述中所謂的攻擊網站,可能就是一個釣魚網站或者黃色網站
例子
我們先假設支付寶存在CSRF漏洞,我的支付寶賬號是zhx,攻擊者的支付寶賬號是xxx。然后我們通過網頁請求的方式
http://zhifubao.com/withdraw?account=zhx&amount=10000&for=luffy
可以把我賬號zhx的10000元轉到我的另外一個賬號luffy上去。
通常情況下,該請求發送到支付寶服務器后,服務器會先驗證該請求是否來自一個合法的session并且該session的用戶已經成功登陸。攻擊者在支付吧也有賬號xxx,他知道上文中的URL可以進行轉賬操作,于是他自己可以發送一個請求
http://zhifubao.com/withdraw?account=zhx&amount=10000&for=xxx 到支付寶后臺。
但是這個請求是來自攻擊者而不是來自我zhx,所以不能通過安全認證,因此該請求作廢。這時,攻擊者xxx想到了用CSRF的方式,他自己做了個黃色網站,在網站中放了如下代碼:
http://zhifubao.com/withdraw?account=zhx&amount=10000&for=xxx
并且通過黃色鏈接誘使我來訪問他的網站。當我禁不住誘惑時就會點了進去,上述請求就會從我自己的瀏覽器發送到支付寶,而且這個請求會附帶我的瀏覽器中的cookie。大多數情況下,該請求會失敗,因為支付寶要求我的認證信息,但是我如果剛訪問支付寶不久,還沒有關閉支付寶頁面,我的瀏覽器中的cookie存有我的認證信息,這個請求就會得到響應,從我的賬戶中轉10000元到xxx賬戶里,而我絲毫不知情,攻擊者拿到錢后逍遙法外。所以以后一定要克制住自己,不要隨便打開別人的鏈接。
透過例子能夠看出,攻擊者并不能通過CSRF攻擊來直接獲取用戶的賬戶控制權,也不能直接竊取用戶的任何信息。他們能做到的,是欺騙用戶瀏覽器,讓其以用戶的名義執行操作。
CSRF 攻擊的對象
在討論如何抵御 CSRF 之前,先要明確 CSRF 攻擊的對象,也就是要保護的對象。從以上的例子可知,CSRF 攻擊是黑客借助受害者的 cookie 騙取服務器的信任,但是黑客并不能拿到 cookie,也看不到 cookie 的內容。另外,對于服務器返回的結果,由于瀏覽器同源策略的限制,黑客也無法進行解析。因此,黑客無法從返回的結果中得到任何東西,他所能做的就是給服務器發送請求,以執行請求中所描述的命令,在服務器端直接改變數據的值,而非竊取服務器中的數據。所以,我們要保護的對象是那些可以直接產生數據改變的服務,而對于讀取數據的服務,則不需要進行 CSRF 的保護。比如銀行系統中轉賬的請求會直接改變賬戶的金額,會遭到 CSRF 攻擊,需要保護。而查詢余額是對金額的讀取操作,不會改變數據,CSRF 攻擊無法解析服務器返回的結果,無需保護。
防御措施
檢查Referer字段
HTTP頭中有一個Referer字段,這個字段用以標明請求來源于哪個地址。在處理敏感數據請求時,通常來說,Referer字段應和請求的地址位于同一域名下。以上文銀行操作為例,Referer字段地址通常應該是轉賬按鈕所在的網頁地址,應該也位于www.examplebank.com之下。而如果是CSRF攻擊傳來的請求,Referer字段會是包含惡意網址的地址,不會位于www.examplebank.com之下,這時候服務器就能識別出惡意的訪問。
這種辦法簡單易行,工作量低,僅需要在關鍵訪問處增加一步校驗。但這種辦法也有其局限性,因其完全依賴瀏覽器發送正確的Referer字段。雖然http協議對此字段的內容有明確的規定,但并無法保證來訪的瀏覽器的具體實現,亦無法保證瀏覽器沒有安全漏洞影響到此字段。并且也存在攻擊者攻擊某些瀏覽器,篡改其Referer字段的可能。
添加校驗token
由于CSRF的本質在于攻擊者欺騙用戶去訪問自己設置的地址,所以如果要求在訪問敏感數據請求時,要求用戶瀏覽器提供不保存在cookie中,并且攻擊者無法偽造的數據作為校驗,那么攻擊者就無法再執行CSRF攻擊。這種數據通常是表單中的一個數據項。服務器將其生成并附加在表單中,其內容是一個偽亂數。當客戶端通過表單提交請求時,這個偽亂數也一并提交上去以供校驗。正常的訪問時,客戶端瀏覽器能夠正確得到并傳回這個偽亂數,而通過CSRF傳來的欺騙性攻擊中,攻擊者無從事先得知這個偽亂數的值,服務器端就會因為校驗token的值為空或者錯誤,拒絕這個可疑請求。
稿源:
https://www.ibm.com/developerworks/cn/web/1102_niugang_csrf/
https://www.jianshu.com/p/e825e67fcf28
https://www.cnblogs.com/hyddd/