- Web漏洞搜索
- (美)彼得·亞沃斯基
- 1411字
- 2021-11-05 10:20:03
4.3 通過POST請求發起CSRF攻擊
如果銀行針對POST請求執行轉賬操作,你將需要使用一種不同的方法來生成CSRF攻擊。攻擊者不能使用<img>標簽,因為<img>標簽不能觸發POST請求。相應地,攻擊者的策略將取決于POST請求的內容。
最簡單的情形是POST請求采用具有application/x-www-form-urlencoded或text/plain取值的內容類型(content-type)。內容類型是瀏覽器在發送HTTP請求時包含的頭部信息。該頭部信息告知接收者HTTP請求體是如何編碼的。下面是一個具有text/plain內容類型的HTTP請求的例子:

內容類型?被標記出來,并且它的類型與請求中的其他字符編碼一起列出。內容類型非常重要,因為瀏覽器依據不同的類型采用不同的處理方式(后面馬上就會介紹到)。
在這種情況下,惡意網站生成一個隱藏的HTML表單并悄悄地發向有漏洞的網站,同時不被目標對象感知到,這是有可能的。表單可以提交一個POST或者GET請求到一個URL,甚至可以提交一些參數值。下面是一段惡意代碼示例,網站上的鏈接會引導Bob訪問這段代碼:


這里,我們用一個表單發起一個到Bob網銀的HTTP POST請求?(由<form>標記中的action屬性指定)。因為攻擊者不想讓Bob看到這個表單,所以每個<input>元素?的type都設置為hidden,這將使得鮑勃在頁面上看不到這些元素。作為最后一步,攻擊者在<script>標簽中編寫了一些JavaScript腳本,從而使得當頁面被加載時能夠自動提交表單?。JavaScript腳本通過調用HTML文檔的getElementByID()方法并以我們在第二行?設置的表單("csrf-form")的ID作為參數來實現這一功能。就像我們之前討論的GET請求一樣,一旦表單提交,瀏覽器就會發起一個HTTP POST請求并發送Bob的cookie到銀行網站,而這將導致銀行轉賬的發生。因為POST請求會觸發網站返回一個HTTP響應消息給瀏覽器,所以攻擊者通過在iFrame中使用display:none屬性來隱藏響應消息?。最后,Bob沒有看到響應消息,也不知道發生了什么。
在某些情況下,網站可能要求POST請求以內容類型application/json進行提交。有時,application/json類型的請求會有一個CSRF令牌(CSRF token)。該令牌是一個隨著HTTP請求一起提交,合法網站用它來驗證請求發起于最初始發起方而不是其他惡意網站。有時POST請求的HTTP體中包含令牌,有時POST請求頭中包含類似X-CSRF-TOKEN這樣的自定義頭信息。當瀏覽器發送一個application/json POST請求給網站時,它一般要先發送一個OPTIONS HTTP請求。網站針對OPTIONS請求會返回一個響應消息,以說明它支持哪些類型的HTTP請求以及接受哪些信任源。這通常叫作預檢OPTIONS調用。瀏覽器讀取響應消息并生成相應的HTTP請求,在我們的網銀例子中就是用來轉賬的POST請求。
如果正確實現,預檢OPTIONS調用能夠抵御某些CSRF漏洞:惡意網站沒有被服務器列入可信網站列表,并且瀏覽器僅允許特定的網站(被稱為白名單網站列表)讀取HTTP OPTIONS響應消息。因此,由于惡意網站不能讀取OPTIONS響應消息,瀏覽器也就不會發送惡意POST請求。
定義網站之間什么時候和如何互相讀取響應消息的規則集合叫作跨源資源共享(CORS)。CORS限制了為該域提供文件服務以及被測試網站允許的域之外的外部域的資源訪問,也包括對JSON響應資源的訪問。換句話說,當開發者使用CORS保護網站時,只有當被測試的網站允許時,你才能提交application/json請求以調用被測試的應用、讀取相應信息或者發起其他調用。有些情況下,你可以通過修改content-type頭信息為application/x-www-form-urlencoded、multipart/form-data或text/plain來繞開這些保護措施。當發起POST請求時,針對該三種類型的content-type,瀏覽器并不會發起預檢OPTIONS調用,因此,CSRF請求攻擊可能會發生效用。如果沒有發生作用,看一下服務器的HTTP響應頭Access-Control-Allow-Origin,確認一下服務器端——它大概率設置了并不信任任意源。當請求從任意源發起,而響應消息頭都跟著變化時,網站可能存在更大的問題,因為它允許任何源讀取服務器的響應消息。這樣將允許黑客在發起CSRF漏洞攻擊之外,還有可能讀取服務器HTTP響應消息中的任何敏感數據。