深入理解CSRF攻擊與防禦
What is CSRF
首先可以先看一段英文原文介紹: Cross Site Reference Forgery works by including malicious code or a link in a page that accesses a web application that the user is believed to have authenticated. If the session for that web application has not timed out, an attacker may execute unauthorized commands. CSRF全稱為跨站請求偽造(Cross-site request forgery),是一種網路攻擊方式,也被稱為 one-click attack 或者 session riding, 縮寫為:CSRF/XSRF。
CSRF攻擊原理
CSRF攻擊可以利用網站對於使用者網頁瀏覽器的信任,挾持使用者當前已登陸的Web應用程式,去執行並非使用者本意的操作。 簡單來說,就是攻擊者盜用了你的身份,以你的名義傳送惡意請求。
CSRF攻擊的大致步驟:
1.登入受信任網站A,並在本地生成Cookie。 2.在不登出A的情況下,訪問危險網站B。 3.B站利用已經驗證的a.com的cookie,偽造使用者請求訪問A。 CS=Cross Site,跨站,從b.com發起 RF=Request Forgery,利用已經驗證的a.com的cookie,從b.com向a.com中的某個頁面performclick.aspx發起頁面的請求,由於在同一個瀏覽器中共享cookie,因此這個請求看起來像a.com自己發出的,因此是請求偽造。
CSRF有一些特點: 1 b.com是從前端攻擊,即從使用者的瀏覽器發起的,因為其他地方(例如b.com的後端)就無法通過共享cookie來偽造請求 2 可以偽造的請求,與a.com存在CSRF漏洞的頁面有關。b.com可以通過GET方式和POST方式,偽造請求給a.com站點;但無法通過Ajax進行請求偽造,這是因為瀏覽器遵循的Ajax的跨域限制。 3 CSRF危害更多是針對可以進行業務動作(增刪改)的頁面,通過偽造請求欺騙站點進行業務辦理。對於查詢頁面存在CSRF漏洞,由於瀏覽器跨域限制,即使請求返回資料,B.com的頁面是無法對資料進行分析或處理,因此查詢頁面的CSRF危害會小很多,或者沒有危害。
How to defense CSRF
在討論如何抵禦 CSRF 之前,先要明確 CSRF 攻擊的物件,也就是要保護的物件。 通過理解CSRF攻擊原理可知,CSRF 攻擊是黑客藉助受害者的 cookie 騙取伺服器的信任,然後去偽造使用者請求。但是黑客並不能拿到 cookie,也看不到 cookie 的內容。另外,對於伺服器返回的結果,由於瀏覽器同源策略的限制,黑客也無法進行解析。因此,黑客無法從返回的結果中得到任何東西,他所能做的就是給伺服器傳送請求,以執行請求中所描述的命令,在伺服器端直接改變資料的值,而非竊取伺服器中的資料。 所以,我們要保護的物件是那些可以直接產生資料改變的服務,而非讀取查詢資料的服務。 在業界目前防禦 CSRF 攻擊主要有四種策略:驗證 HTTP Referer 欄位;在請求地址中新增 token 並驗證;在 HTTP 頭中自定義屬性並驗證;加驗證碼。下面就分別對這三種策略進行詳細介紹。
驗證 HTTP Referer 欄位
根據 HTTP 協議,在 HTTP 頭中有一個欄位叫 Referer,它記錄了該 HTTP 請求的來源地址。要防禦 CSRF 攻擊,只需要針對每一個可以改變資料的服務請求,驗證其 Referer 值,如果是以正確的域名開頭,則說明該請求是合法的。如果 Referer 是其他網站的話,則有可能是黑客的 CSRF 攻擊,拒絕該請求。 但這種方法並非萬無一失,對於某些瀏覽器,比如 IE6 或 FF2,目前已經有一些方法可以篡改 Referer 值。如果黑客能夠篡改 Referer 值,這樣就可以通過驗證,從而進行 CSRF 攻擊。
在請求地址中新增 token 並驗證
要抵禦 CSRF,關鍵在於在請求中放入黑客所不能偽造的資訊,並且該資訊不存在於 cookie 之中。簡而言之就是在客戶端頁面增加偽隨機數。 在 HTTP 請求中以引數的形式加入一個隨機產生的 token,並在伺服器端建立一個攔截器來驗證這個 token,如果請求中沒有 token 或者 token 內容不正確,則認為可能是 CSRF 攻擊而拒絕該請求。 這種防禦方法要比檢查 Referer 要安全一些,token 可以在使用者登陸後產生並放於 session 之中,然後在每次請求時把 token 從 session 中拿出,與請求中的 token 進行比對。
在 HTTP 頭中自定義屬性並驗證
這種方法也是使用 token 並進行驗證,和上一種方法不同的是,這裡並不是把 token 以引數的形式置於 HTTP 請求之中,而是把它放到 HTTP 頭中自定義的屬性裡。服務端的CSRF防禦方法很多樣,但總的思想都是一致的,就是在客戶端頁面增加偽隨機數。
驗證碼
每次的使用者提交都需要使用者在表單中填寫一個圖片上的隨機字串,但可能會降低使用者體驗。
部分參考資料
總結
本文主要是結合自己所學知識,探討了一些對CSRF的一些理解,CSRF 是一種危害非常大的攻擊,又很難以防範。目前幾種防禦策略雖然可以很大程度上抵禦 CSRF 的攻擊,但並沒有一種完美的解決方案。在這之前,只有充分重視 CSRF,根據系統的實際情況選擇最合適的策略,這樣才能把 CSRF 的危害降到最低。 希望能對大家有所幫助~ 有問題歡迎留言交流,不足之處還請多多指正。