天天看點

【安全系列】CSRF攻擊與防禦

一、CSRF概述

攻擊者盜用了你的身份,以你的名義發送惡意請求,對伺服器來說這個請求是完全合法的,但是卻完成了攻擊者所期望的一個操作。對于CSRF而言,它的攻擊有兩個關鍵點,跨站點的請求與請求是僞造的。

二、CSRF攻擊的危害

  • 篡改目标網站上的使用者資料
  • 盜取使用者隐私資料
  • 作為其他攻擊向量的輔助攻擊手法
  • 傳播CSRF蠕蟲

三、攻擊原理及過程

我們先建構一個場景。

目标網站A:www.a.com

惡意網站B:www.b.com

兩個域不一樣,目标網站A上有一個删除文章的功能,通常是使用者點選“删除連結”時才會删除指定的文章,這個連結是www.a.com/blog/del?id=1,id代表不同的文章。

【XSS實作】

這樣删除文章實際上就是發送了一個get請求,那麼如果目标網站A存在XSS漏洞,執行JS腳本無同源政策限制,就可以使用XSS的形式來完成文章的删除操作。

  • 使用AJAX發出get請求,請求id=1,請求目标位址是www.a.com/blog/del。
  • 或者動态建立一個标簽對象(如img、script、iframe)等,将他麼的src指向這個連結www.a.com/blog/del?id=1,發出get請求。
  • 然後欺騙使用者通路存在XSS腳本漏洞的頁面,則發生攻擊。

    【CSRF實作】

  • 在惡意網站B上寫一個CSRF頁面(www.b.com/csrf.html)
  • 使用<img src=http://www.a.com/blog/del?id=1 />
  • 然後欺騙已經登陸了目标網站A的使用者通路www.b.com/csrf.html頁面,由于使用者登陸通路過目标A網站不久,它的浏覽器與A網站之間的session尚未過期,浏覽器中的cookie包含了使用者的認證資訊。而在IE浏覽器中,預設不允許目标A網站的本地cookie在跨域請求中攜帶,除非在HTTP的響應頭設定P3P,這個響應頭告訴浏覽器允許網站跨域請求資源時帶上目标A網站的使用者本地cookie,而對于記憶體cookie是被預設允許的。

四、CSRF攻擊分類

4.1 HTML CSRF攻擊

同樣是上面的場景,發起的CSRF請求都屬于HTML元素發出的,這一類是最普通的CSRF攻擊。

下面是常見的可以發起這樣的請求的HTML元素。

<link href="">
<img src="">
<img lowsrc="">
<img dynsrc="">
<meta http-equiv="refresh" content="0; url=">
<iframe src="">
<frame src="">
<script src="">
<bgsound src="">
<embend src="">
<video src="">
<audio src="">
<a href="">
<table background="">
//CSS樣式中
@import ""
background: url("")複制代碼           

複制

4.2 JSON HiJacking 攻擊

為了了解JSON HiJacking攻擊,我們先來看看一種跨域解決方案:JSONP。

JSONP(JSON with Padding)是一個非官方的協定,是Web前端的JavaScript跨域擷取資料的一種方式。我們知道,JavaScript在讀寫資料時受到同源政策的限制,不可以讀寫其他域的資料,于是大家想出了這樣一種辦法:

【html代碼】

【安全系列】CSRF攻擊與防禦

【php代碼】

【安全系列】CSRF攻擊與防禦

可以看到,前端先是定義了jsonpCallback函數來處理後端傳回的JSON資料,然後利用script标簽的src屬性跨域擷取資料(前面說到帶src屬性的html标簽都可以跨域),并且把剛才定義的回調函數的名稱傳遞給了後端,于是後端構造出“jsonpCallback({“a”:1, “b”:2, “c”:3, “d”:4, “e”:5})”的函數調用過程傳回到前端執行,達到了跨域擷取資料的目的。

當使用者通過身份認證之後,前端會通過JSONP的方式從服務端擷取該使用者的隐私資料,然後在前端進行一些處理,如個性化顯示等等。這個JSONP的調用接口如果沒有做相應的防護,就容易受到JSON HiJacking的攻擊。

【攻擊代碼】

【安全系列】CSRF攻擊與防禦

攻擊者在頁面中構造了自己的回調函數,把擷取的資料都發送到了自己的伺服器上。如果受害者在已經經過身份認證的情況下通路了攻擊者構造的頁面,其隐私将暴露無疑。

4.3 Flash CSRF攻擊

在flash的世界同樣遵循着同源政策,發起CSRF攻擊是通過ActionScript腳本來完成的,正常來講Flash CSRF攻擊,通常是兩個目的:

  • 跨域擷取隐私資料
  • 跨域送出資料操作,做一些增、删、改之類的操作。

【跨域擷取隐私資料】

如果目标網站的根目錄存在crossdomain.xml檔案,配置如下:

【安全系列】CSRF攻擊與防禦

配置中allow-access-from domain="*"表示允許任務域請求本域的資源,如果使用者登陸了目标網站,被欺騙通路包含惡意Flash的網頁時,隐私就有可能被盜走。

【跨域送出資料操作】

通常情況下會使用HTML CSRF攻擊的形式發起攻擊:

【安全系列】CSRF攻擊與防禦

五、CSRF漏洞檢測

檢測CSRF漏洞是一項比較繁瑣的工作,最簡單的方法就是抓取一個正常請求的資料包,去掉Referer字段後再重新送出,如果該送出還有效,那麼基本上可以确定存在CSRF漏洞。

随着對CSRF漏洞研究的不斷深入,不斷湧現出一些專門針對CSRF漏洞進行檢測的工具,如CSRFTester,CSRF Request Builder等。

以CSRFTester工具為例,CSRF漏洞檢測工具的測試原理如下:使用CSRFTester進行測試時,首先需要抓取我們在浏覽器中通路過的所有連結以及所有的表單等資訊,然後通過在CSRFTester中修改相應的表單等資訊,重新送出,這相當于一次僞造用戶端請求。如果修改後的測試請求成功被網站伺服器接受,則說明存在CSRF漏洞,當然此款工具也可以被用來進行CSRF攻擊。

六、CSRF攻擊防禦

【HTTP Referer 字段校驗】

比如上一個場景,惡意攻擊被發起時,請求的Referer會指向惡意網站,是以要防禦CSRF攻擊,可能對Referer字段校驗,如果不是本域或者指定域過來的請求,不予通過校驗。

這種方法在大部分的場景是可行的。但也不是萬無一失的。如果使用者在浏覽器設定發送請求是不提供Referer 時,而被誤認為是惡意攻擊,拒絕提供服務。

【token 驗證】

在HTTP請求參數中添加一個随機的token值,服務端對token統一攔截校驗,如果沒有token值,或者token值不對,拒絕提供服務。

【自定義屬性驗證】

這個方法也是進行token驗證,不同的是這種方法并不是把token置于請求參數中,而是在HTTP請求頭中自定義屬性。通過XMLHttpRequest 這個類,可以一次性給所有該類請求加上 csrftoken 這個 HTTP 頭屬性,并把 token 值放入其中。這樣解決了上種方法在請求中加入 token 的不便,同時,通過 XMLHttpRequest 請求的位址不會被記錄到浏覽器的位址欄,也不用擔心 token 會透過 Referer 洩露到其他網站中去。