Web安全漏洞之CSRF

來自專欄 ThinkJS9 人贊了文章

什麼是 CSRF

在了解 CSRF 之前我們需要科普兩個前提。首先是登錄許可權驗證的方式有很多種,目前絕大多數網站採用的還是 session 會話任務的方式。session 機制簡單的來說就是服務端使用一個鍵值對記錄登錄信息,同時在 cookie 中將 session id(即剛才說的鍵)存儲到 cookie 中。另外我們又知道瀏覽器中 HTTP(s) 請求是會自動幫我們把 cookie 帶上傳給服務端的。這樣在每次請求的時候通過 cookie 獲取 session id,然後通過它在服務端獲取登錄信息即可完成用戶許可權的校驗。

本來這也是個不錯的功能。但是由於 cookie 實在是太開放了,如果一個用戶在 A 網站登錄了,如果用戶在 B 網站訪問的時候發送了一個 A 網站的請求,那麼這個請求其實是帶有這個用戶在 A 網站的登錄信息的。如果這時候 B 站的 A 網站請求是用戶不知道的,那就是非常嚴重的危害了。以上的過程就是跨站請求攻擊,即 Cross-Site Request Forgery,即 CSRF。

CSRF 的危害

簡單總結 CSRF 漏洞就是利用網站許可權校驗方面的漏洞在用戶不知覺的情況下發送請求,達到「偽裝」用戶的目的。攻擊者利用 CSRF 實現的攻擊主要有以下幾種:

  1. 攻擊者能夠欺騙受害用戶完成該受害者所允許的任一狀態改變的操作,比如:更新賬號細節,完成購物,註銷甚至登錄等操作
  2. 獲取用戶的隱私數據
  3. 配合其他漏洞攻擊
  4. CSRF 蠕蟲

其中 CSRF 蠕蟲如其名所指就是產生蠕蟲效果,會將 CSRF 攻擊一傳十,十傳百。如:某社區私信好友的介面和獲取好友列表的介面都存在CSRF漏洞,攻擊者就可以將其組合成一個CSRF蠕蟲——當一個用戶訪問惡意頁面後通過CSRF獲取其好友列表信息,然後再利用私信好友的CSRF漏洞給其每個好友發送一條指向惡意頁面的信息,只要有人查看這個信息里的鏈接,CSRF蠕蟲就會不斷傳播下去,其可能造成的危害和影響非常巨大!

防禦方法

從上文的描述中我們可以知道 CSRF 有兩個特點:利用 cookie 自動攜帶的特性以及跨站攻擊。那麼針對這兩個特性可以使用如下解決方法。

檢查 Referer 欄位

大家都知道 HTTP 頭中有一個 Referer 欄位,這個欄位用以標明請求來源於哪個地址。通過在網站中校驗請求的該欄位,我們能知道請求是否是從本站發出的。我們可以拒絕一切非本站發出的請求,這樣避免了 CSRF 的跨站特性。

const { parse } = require(url);module.exports = class extends think.Logic { indexAction() { const referrer = this.ctx.referrer(); const {host: referrerHost} = parse(referrer); if(referrerHost !== xxx) { return this.fail(REFERRER_ERROR); } }}

同樣以 ThinkJS 為例,只要在 Logic 中簡單判斷下即可。這種方式利用了客戶端無法構造 Referrer 的特性,雖然簡單,不過當網站域名有多個,或者經常變換域名的時候會變得非常的麻煩,同時也具有一定的局限性。

Token 驗證

由於 CSRF 是利用了瀏覽器自動傳遞 cookie 的特性,另外一個防禦思路就是校驗信息不通過 cookie 傳遞,在其他參數中增加隨機加密串進行校驗。這裡又有兩種辦法:

  1. 隨機字元串:為每一個提交增加一個隨機串參數,該參數服務端通過頁面下發,每次請求的時候補充到提交參數中,服務端通過校驗該參數是否一致來判斷是否是用戶請求。由於 CSRF 攻擊中攻擊者是無從事先得知該隨機字元串的值,所以服務端就可以通過校驗該值拒絕可以請求。
  2. JWT:實際上除了 session 登錄之外,現在越來越流行 JWT token 登錄校驗。該方式是在前端記錄登錄 token,每次請求的時候通過在 Header 中添加認證頭的方式來實現登錄校驗過程。由於 CSRF 攻擊中攻擊者無法知道該 token 值,通過這種方式也是可以防止 CSRF 攻擊的。當然 token 登錄方式除了 JWT 之外還有 OAuth 等很多種方式,關於如何在 ThinkJS 中使用 JWT 的話可以參考之前的文章。

怡紅公子:ThinkJS JWT 鑒權實踐?

zhuanlan.zhihu.com圖標

後記

除了上面說到的 cookie 登錄問題造成的 CSRF 攻擊,還有就是增刪改等操作使用 GET 請求完成,當該請求未校驗登錄信息的時候也容易造成 CSRF 攻擊。當然這種就比較低級了,不過也還是需要注意。特別是當下 SPA 的流行,越來越多的 AJAX 請求,我們更是要注意 CSRF 攻擊的可能。

參考資料:

  • 《跨站請求偽造》
  • 《Cross-Site Request Forgery (CSRF)》
  • 《從防禦認識CSRF》
  • 《Cross-site Request Forgery/CSRF》

推薦閱讀:

相关文章