CSRF 攻擊和防御原理
CSRF 是跨站點(diǎn)請(qǐng)求偽造 (Cross—Site Request Forgery),存在巨大的危害性,本節(jié)講解 CSRF 攻擊和防御的原理。
1. 什么是 CSRF 攻擊
CSRF 是英文 Cross Site Request Forgery 的縮寫,中文翻譯為 “跨站請(qǐng)求偽造”,它是一種挾制用戶在當(dāng)前已登錄的 Web 應(yīng)用程序上執(zhí)行非本意的操作的攻擊方法。
用戶使用瀏覽器登錄網(wǎng)站,通過(guò)身份驗(yàn)證后,來(lái)自該瀏覽器的請(qǐng)求會(huì)得到授權(quán):在服務(wù)端可以執(zhí)行新增數(shù)據(jù)、修改數(shù)據(jù)、刪除數(shù)據(jù)等操作。但是,這樣的身份驗(yàn)證機(jī)制存在一個(gè)漏洞:只能保證請(qǐng)求發(fā)自某個(gè)登錄用戶的瀏覽器,卻不能保證請(qǐng)求本身是用戶自愿發(fā)出的。
攻擊者利用身份驗(yàn)證漏洞可以挾制用戶在當(dāng)前已登錄的 Web 應(yīng)用程序上執(zhí)行非本意的操作。
2. CSRF 攻擊的過(guò)程
2.1 案例簡(jiǎn)介
本小節(jié)通過(guò)一個(gè)具體的例子,講解 CSRF 工具的步驟。案例的假設(shè)如下:
- 存在一個(gè)銀行網(wǎng)站,提供在線轉(zhuǎn)賬功能;
- 用戶登錄銀行后,才可以使用在線轉(zhuǎn)賬功能;
- 銀行中存在兩個(gè)賬戶:受害者賬戶、攻擊者賬戶;
- 存在一個(gè)惡意網(wǎng)站,當(dāng)訪問(wèn)該惡意網(wǎng)站時(shí),會(huì)自動(dòng)向銀行網(wǎng)站提出轉(zhuǎn)賬請(qǐng)求。
如果受害者沒(méi)有退出銀行網(wǎng)站的情況下訪問(wèn)惡意網(wǎng)站,因?yàn)槭芎φ咭呀?jīng)通過(guò)了銀行網(wǎng)站的身份驗(yàn)證,因此發(fā)出的轉(zhuǎn)賬請(qǐng)求會(huì)通過(guò)銀行網(wǎng)站的授權(quán),即攻擊者完成了攻擊。
2.2 攻擊的步驟
發(fā)動(dòng) CSRF 攻擊的步驟如下圖所示:

2.2.1 登錄
受害者使用用戶名、密碼登錄銀行網(wǎng)站。
2.2.2 驗(yàn)證通過(guò)
銀行網(wǎng)站根據(jù)用戶名、密碼查詢數(shù)據(jù)庫(kù),如果匹配,則在 Session 中記錄用戶已經(jīng)通過(guò)身份驗(yàn)證。
銀行網(wǎng)站提供了轉(zhuǎn)賬的功能,在實(shí)現(xiàn)轉(zhuǎn)賬功能時(shí),首先在 Session 中檢查是用戶是否是登錄用戶,如果是登錄用戶,則允許執(zhí)行轉(zhuǎn)賬操作;如果不是登錄用戶,則不允許執(zhí)行轉(zhuǎn)賬操作。
2.2.3 被誘導(dǎo)
攻擊者創(chuàng)辦了一個(gè)惡意網(wǎng)站,提供一些吸引人的內(nèi)容(例如:色情、賭博、盜版小說(shuō)等信息),誘導(dǎo)受害者訪問(wèn)惡意網(wǎng)站。
2.2.4 惡意 HTML
當(dāng)受害者訪問(wèn)惡意網(wǎng)站時(shí),惡意網(wǎng)站傳輸給受害者一段惡意的 HTML 代碼,惡意的 HTML 代碼向銀行發(fā)起轉(zhuǎn)賬請(qǐng)求,代碼可能如下:
<form action='http://www.bank.com/transfer' method='post'>
<input type="text" name="name" value="hacker" placeholder="收款賬戶"/>
<input type="text" name="amount" value="100" placeholder="轉(zhuǎn)賬數(shù)量"/>
<input type="submit" id="submit" value="轉(zhuǎn)賬">
</form>
<script>
var submit = document.getElementById('submit');
submit.click();
</script>
在第 1 行,定義了一個(gè)向銀行網(wǎng)站提出轉(zhuǎn)賬請(qǐng)求的表單,通過(guò) POST 方法向頁(yè)面 http://www.bank.com/transfer’ 提出轉(zhuǎn)賬請(qǐng)求。
在第 2 行,定義了一個(gè)名稱為 ‘name’、值為 ‘hacker’ 的文本字段,表示轉(zhuǎn)賬的收款賬戶是 ‘hacker’。
在第 3 行,定義了一個(gè)名稱為 ‘a(chǎn)mount’、值為 ‘100’ 的文本字段,表示轉(zhuǎn)賬的數(shù)量是 100。
在第 8 行和第 9 行,找到提交按鈕,模擬提交按鈕的 click 操作,實(shí)現(xiàn)了自動(dòng)提交表單。即:用戶瀏覽器訪問(wèn)這段惡意的 HTML 代碼后,會(huì)自動(dòng)向銀行網(wǎng)站發(fā)出轉(zhuǎn)賬 100 元的請(qǐng)求。顯然,這次轉(zhuǎn)賬不是受害者用戶的本意,是攻擊者偽造的用戶請(qǐng)求。
2.2.5 轉(zhuǎn)賬
受害者的瀏覽器收到惡意的 HTML 后,執(zhí)行惡意的 HTML 中的 Javascript 代碼,自動(dòng)向銀行提出了一個(gè)轉(zhuǎn)賬請(qǐng)求。
銀行網(wǎng)站收到轉(zhuǎn)賬請(qǐng)求后進(jìn)行處理,如果受害者沒(méi)有退出銀行網(wǎng)站的登錄,此次轉(zhuǎn)賬請(qǐng)求可以通過(guò)身份驗(yàn)證,可以正常完成轉(zhuǎn)賬的功能。
通過(guò)以上的 5 個(gè)步驟,攻擊者成功的挾制了受害者,在當(dāng)前已登錄的銀行網(wǎng)站上執(zhí)行非本意的轉(zhuǎn)賬操作。
3. CSRF 防御的方法
在業(yè)界目前防御 CSRF 攻擊有如下策略:
3.1 驗(yàn)證 HTTP Referer 字段
HTTP Referer 字段簡(jiǎn)介
在 HTTP 請(qǐng)求頭里有個(gè) Referer 字段,用于表明請(qǐng)求的來(lái)源地址。以向銀行發(fā)出轉(zhuǎn)賬請(qǐng)求為例,說(shuō)明 Referer 字段。
1. 用戶正常發(fā)出轉(zhuǎn)賬請(qǐng)求
用戶登錄銀行網(wǎng)站成功后,在網(wǎng)站首頁(yè) http://www.bank.com/,存在一個(gè)轉(zhuǎn)賬按鈕;用戶通過(guò)點(diǎn)擊頁(yè)面上的轉(zhuǎn)賬按鈕進(jìn)行轉(zhuǎn)賬,向銀行發(fā)出轉(zhuǎn)賬請(qǐng)求
| 屬性 | 描述 |
|---|---|
| 請(qǐng)求的地址 | http://www.bank.com/transfer |
| 請(qǐng)求的 Referer | http://www.bank.com/ |
可以看出:請(qǐng)求的地址和請(qǐng)求的 Referer 是屬于相同的域名。
2. 攻擊者通過(guò) CSRF 攻擊發(fā)出轉(zhuǎn)賬請(qǐng)求
如果用戶被誘導(dǎo)進(jìn)入惡意網(wǎng)站 http://www.malicious.com,在惡意網(wǎng)站的頁(yè)面中向銀行發(fā)起轉(zhuǎn)賬請(qǐng)求,請(qǐng)求的屬性如下:
| 屬性 | 描述 |
|---|---|
| 請(qǐng)求的地址 | http://www.bank.com/transfer |
| 請(qǐng)求的 Referer | http://www.malicious.com/ |
可以看出:請(qǐng)求的地址和請(qǐng)求的 Referer 是屬于不同的域名。
3.1.2 驗(yàn)證 HTTP Referer 字段
正常情況下,Referer 字段和請(qǐng)求的地址是位于同一域名下的。如果是 CSRF 攻擊發(fā)起的請(qǐng)求,那么 Referer 字段和請(qǐng)求的地址就不是同一域名了,因此,服務(wù)器通過(guò)驗(yàn)證 HTTP Referer 字段就能識(shí)別出 CSRF 攻擊。
該方法的優(yōu)點(diǎn)在于:只需要給所有安全敏感的請(qǐng)求統(tǒng)一增加一個(gè)攔截器來(lái)檢查 Referer 的值就可以防御所有的 CSRF 攻擊;特別是對(duì)于當(dāng)前現(xiàn)有的系統(tǒng),不需要改變當(dāng)前系統(tǒng)的任何已有代碼和邏輯,沒(méi)有風(fēng)險(xiǎn),非常便捷。
該方法的缺點(diǎn)在于:攻擊者能夠篡改請(qǐng)求頭的 Referer 字段內(nèi)容,從而欺騙服務(wù)器;有可能無(wú)法獲取 Referer 的值,因?yàn)?Referer 值會(huì)記錄下用戶的訪問(wèn)來(lái)源,有些用戶認(rèn)為這樣會(huì)侵犯到他們自己的隱私權(quán),因此,用戶自己可以設(shè)置瀏覽器使其在發(fā)送請(qǐng)求時(shí)不再提供 Referer。
3.2 在請(qǐng)求中添加 Token 并驗(yàn)證
目前業(yè)界對(duì) CSRF 的防御,流行的做法是使用一個(gè) Token(Anti CSRF Token)。使用 Token 防御 CSRF 攻擊的步驟如下:
- 用戶訪問(wèn)某個(gè)安全相關(guān)的頁(yè)面,例如銀行的轉(zhuǎn)賬頁(yè)面;
- 服務(wù)端生成一個(gè)隨機(jī)的 Token,放在用戶的 Session 中;
- 在安全相關(guān)的頁(yè)面附帶上 Token,返回給客戶端;
- 用戶提交請(qǐng)求后,服務(wù)端獲取兩個(gè) Token:驗(yàn)證表單中的 Token、用戶 Session 中的 Token,如果一致則為合法請(qǐng)求,不一致則識(shí)別為 CSRF 攻擊。
4. 小結(jié)
本節(jié)講解了 CSRF 的概念,如何實(shí)施 CSRF 攻擊以及如何防御 CSRF 攻擊,使用思維導(dǎo)圖概括如下:

朱廣蔚 ·
2025 imooc.com All Rights Reserved |