密碼學系列之:csrf跨站點請求僞造

簡介

CSRF的全稱是Cross-site request forgery跨站點請求僞造,也稱爲一鍵攻擊或會話劫持,它是對網站的一種惡意利用,主要利用的是已授權用戶對於站點的信任,無辜的最終用戶被攻擊者誘騙提交了他們不希望的Web請求。 惡意網站可以通過多種方式來發送此類命令。 例如,特製的圖像標籤,隱藏的表單和JavaScript XMLHttpRequests都可以在用戶不交互甚至不知情的情況下工作。

如果發生了CSRF攻擊,可能導致客戶端或服務器數據意外泄漏,會話狀態更改或者修改用戶的信息。

CSRF的特點

在CSRF的惡意攻擊中,攻擊者的目標是讓被攻擊者在不知不覺中向有權限訪問的網站提交惡意的web請求。通過對該請求進行精心的設計,使其包含URL參數,Cookie和其他對處理該請求的Web服務器而言正常顯示的數據。通過保存在用戶Web瀏覽器中的cookie進行身份驗證的用戶可能會在不知不覺中將HTTP請求發送到信任該用戶的站點,從而導致不必要的操作。

爲什麼會有這樣的攻擊呢?因爲對於web瀏覽器來說,它們將在發送給該域的任何Web請求中自動且無形地包含給定域使用的任何cookie。 CSRF攻擊利用了此屬性,因爲瀏覽器發出的任何Web請求都將自動包含受害者登錄網站時創建的任何cookie(包括會話cookie和其他cookie)。如果用戶被誘騙通過瀏覽器無意中提交了請求,這些自動包含的cookie將使僞造也能夠通過目標服務器的認證,從而產生惡意攻擊。

爲了生成這樣的攻擊URL,惡意攻擊者需要構造一個可以被執行的web請求,比如在目標頁面上更改帳戶密碼。攻擊者可以將該鏈接嵌入攻擊者控制範圍內的頁面上。比如它可以嵌入到發送給受害者的電子郵件中的html圖像標籤中,當受害者打開其電子郵件時,該圖像會自動加載。一旦受害者單擊了鏈接,他們的瀏覽器將自動包含該網站使用的所有cookie,並將請求提交到Web服務器。 Web服務器將會執行該惡意請求。

CSRF的歷史

早在2001年,就有人開始使用它來進行攻擊了。不過因爲攻擊使用的是用戶自己的IP地址,看起來就像是用戶自己的一個正常的請求,所以很少有直接的攻擊證據。目前知道的比較有名的CSRF攻擊如下:

2006年Netflix爆出了衆多CSRF漏洞,攻擊者可以更改受害者的賬戶收貨地址,從而爲攻擊者自己來購買商品。
YouTube在2008年也受到了CSRF的攻擊,這使得任何攻擊者都幾乎可以執行任何用戶的所有操作。
McAfee Secure也曾經受到過CSRF的攻擊,它允許攻擊者更改公司系統。
2018年,一些路由器也受到了CSRF的攻擊,從而能夠修改路由器的DNS設置。

CSRF攻擊的限制

要想達成CSRF攻擊是需要一定的條件的,事實上CSRF攻擊也並不是一個很簡單的事情,必須滿足下面的條件:

  1. 目標web服務沒有檢查請求的referrer header,如果只允許同源請求的話,則無法使用CSRF。
  2. 攻擊者必須在目標站點上找到表單提交文件,或者發現具有攻擊屬性的URL,該URL會執行某些操作(例如,轉賬或更改受害者的電子郵件地址或密碼)。
  3. 攻擊者必須爲所有表單或URL輸入確定正確的值;如果要求它們中的任何一個是攻擊者無法猜到的祕密身份驗證值或ID,則攻擊很可能會失敗(除非攻擊者在他們的猜測中非常幸運)。
  4. 當受害者登錄到目標站點時,攻擊者必須誘使受害者進入帶有惡意代碼的網頁。
  5. 攻擊者只能發出請求,但是無法看到目標站點響應攻擊請求發回給用戶的內容,如果操作具有連續性的話,後續的CSRF攻擊將無法完成。

CSRF攻擊的防範

因爲web瀏覽器對不同的HTTP請求處理方式是不同的,所以針對CSRF攻擊的防範跟HTTP請求的方法相關。

在HTTP GET中,使用CSRF攻擊非常簡單,比如將攻擊URL帶入IMG標籤就會自動加載。但是,根據HTTP規範,GET方法不應該被用於修改數據。使用GET進行更新數據操作的應用程序應切換到HTTP POST或使用反CSRF保護。

CSRF的HTTP POST漏洞取決於使用情況:
在最簡單的POST形式中,數據編碼爲查詢字符串(field1 = value1&field2 = value2),可以使用簡單的HTML形式輕鬆實現CSRF攻擊,這就意味着必須採取反CSRF措施。

如果以其他任何格式(JSON,XML)發送數據,標準方法是使用XMLHttpRequest發出POST請求,並通過同源策略(SOP)和跨域資源共享(CORS)防止CSRF攻擊。

其他HTTP方法(PUT,DELETE等)只能使用具有同源策略(SOP)和跨域資源共享(CORS)來防止CSRF的XMLHttpRequest請求;但是,在使用Access-Control-Allow-Origin:*標頭明確禁用它們的網站上,這些措施將無效。

下面我們來具體講解幾個防範CSRF的技巧

STP技術

STP的全稱是Synchronizer token pattern。也就是說在所有的HTML表單上包含一個隱藏的token字段,token是可以由很多種方法來生成,只要保證其隨機性就行了。因爲攻擊者無法預測到這個token的值,所以無法進行CSRF攻擊。比如下面的代碼:

<input type="hidden" name="csrfmiddlewaretoken" value="KbyUmhTLMpYj7CD2di7JKP1P3qmLlkPt" />

STP是兼容性最好的,因爲它僅依賴HTML,但是每個請求都帶上token會增加程序的複雜性, 由於token是唯一且不可預測的,因此還會強制執行適當的事件順序,這會引發一些可用性的問題(例如用戶打開多個選項卡)。 可以通過使用每個會話CSRF令牌而不是每個請求CSRF令牌來放寬它。

Cookie-to-header token

如果web應用程序主要使用javascript來進行交互的話,可以考慮使用這種方式。

在初次訪問web服務的時候,會在cookie中設置一個隨機令牌,該cookie無法在跨域請求中訪問:

Set-Cookie: csrf_token=i8XNjC4b8KVok4uw5RftR38Wgp2BFwql; Expires=Thu, 23-Jul-2015 10:25:33 GMT; Max-Age=31449600; Path=/; Domain=.wikipedia.org; SameSite=Lax; Secure

在客戶端運行javascript的時候,從cookie中讀取這個token值,並將其複製到隨每個事務請求發送的自定義HTTP標頭中

X-Csrftoken:i8XNjC4b8KVok4uw5RftR38Wgp2BFwql

服務器驗證令牌的存在和完整性。因爲從惡意文件或電子郵件運行的JavaScript無法成功讀取cookie值以複製到自定義標頭中。即使將csrf token cookie與惡意請求一起自動發送,服務器任然需要有效的X-Csrf-Token頭。

這項技術已經被很多框架實現了,比如Django 和AngularJS,因爲令牌在整個用戶會話中保持不變,所以它可以與AJAX應用程序很好地協同工作。

注意,使用這項技術,必須確保同源政策。

Double Submit Cookie

這個方法與cookie-to-header方法類似,但不涉及JavaScript,站點可以將CSRF令牌設置爲cookie,也可以將其作爲每個HTML表單中的隱藏字段插入。 提交表單後,站點可以檢查cookie令牌是否與表單令牌匹配。 同源策略可防止攻擊者在目標域上讀取或設置Cookie,因此他們無法以其精心設計的形式放置有效令牌。

與同步器模式相比,此技術的優勢在於不需要將令牌存儲在服務器上。

SameSite cookie attribute

當服務器設置cookie時,可以包含一個附加的“ SameSite”屬性,指示瀏覽器是否將cookie附加到跨站點請求。 如果將此屬性設置爲“strict”,則cookie僅在相同來源的請求中發送,從而使CSRF無效。 但是,這需要瀏覽器識別並正確實現屬性,並且還要求cookie具有“Secure”標誌。

Client-side safeguards

瀏覽器本身可以通過爲跨站點請求提供默認拒絕策略,來阻止CSRF。比如Mozilla Firefox的RequestPolicy或者Firefox和Google Chrome / Chromium 的uMatrix之類。但是,這可能會嚴重干擾許多網站的正常運行。

有些瀏覽器擴展程序如CsFire擴展(也適用於Firefox)可以通過從跨站點請求中刪除身份驗證信息,從而減少對正常瀏覽的影響。

本文已收錄於 http://www.flydean.com/csrf/

最通俗的解讀,最深刻的乾貨,最簡潔的教程,衆多你不知道的小技巧等你來發現!

歡迎關注我的公衆號:「程序那些事」,懂技術,更懂你!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章