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

簡介

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

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

CSRF的特色

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

爲何會有這樣的攻擊呢?由於對於web瀏覽器來講,它們將在發送給該域的任何Web請求中自動且無形地包含給定域使用的任何cookie。 CSRF攻擊利用了此屬性,由於瀏覽器發出的任何Web請求都將自動包含受害者登陸網站時建立的任何cookie(包括會話cookie和其餘cookie)。若是用戶被誘騙經過瀏覽器無心中提交了請求,這些自動包含的cookie將使僞造也可以經過目標服務器的認證,從而產生惡意攻擊。web

爲了生成這樣的攻擊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攻擊也並非一個很簡單的事情,必須知足下面的條件:cookie

  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保護。ide

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令牌來放寬它。

若是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應用程序很好地協同工做。

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

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

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

當服務器設置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/

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

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

相關文章
相關標籤/搜索