什么是CSRF?
跨站請求偽造(也稱為 CSRF)是一種 Web 安全漏洞,允許攻擊者誘導用戶執(zhí)行他們不打算執(zhí)行的操作。它允許攻擊者部分規(guī)避同源策略,該策略旨在防止不同網(wǎng)站相互干擾。
GET?POST?
實際上,CSRF不只是只有GET請求可以發(fā)起,POST請求也可以發(fā)起。
通常情況下,CSRF一般都是采用<iframe>, <img><script>這些帶有src
屬性的標簽發(fā)起的,而這些標簽只能發(fā)起一次GET請求,不能發(fā)起一次POST請求,但是對于有些網(wǎng)站來說,這些操作并沒用嚴格區(qū)分POST或者GET操作,所以,攻擊者可以使用GET來請求表單的提交地址。比如在PHP中,如果使用的是$_REQUEST獲取變量,而不是$_POST獲取變量,就會發(fā)生此問題。(這句化就是說,有些網(wǎng)站對于一些重要的請求操作,應該是只能用POST發(fā)起請求的,但是他沒有嚴格限制,使得GET也能發(fā)起請求)
對于一個表單來說,用戶往往可以通過使用GET來提交表單,比如
<form action="/register" id='register' method='POST'>
<input type=text name='username' value=''/>
<input type=password name='password',value=''/>
<input type=submit name='submit' value='submit'>
</form>
我們可以嘗試構造一個GET請求:
http:
/
/
host
/
register?username
=
test&password
=
passwd
如果服務器沒有對請求方法進行限制,則這個請求會通過。
如果服務器已經(jīng)區(qū)分了POST和GET,對于只能用POST提交的鏈接,我們也可以構造出一個POST請求。
比如,在一個頁面中構造好一個form表單,然后使用Javascript自動提交這個表單。比如,攻擊者在www.b.com/test/html下編寫如下代碼:
<form action="http://www.a.com/register" id='register' method='POST'>
<input type=text name='username' value=''/>
<input type=password name='password',value=''/>
<input type=submit name='submit' value='submit'>
</form>
<script>
var f = documentElementById('register');
f.inouts[0].value='test';
f.inputs[1].value='password';
f.submit;
</script>
攻擊者如果將這個頁面隱藏在一個不可見的iframe窗口中,則整個自動提交表單的過程,對于用戶來說也是不可見的。
CSRF 攻擊的影響是什么?
在成功的CSRF 攻擊中。攻擊者會導致受害者用戶無意中執(zhí)行某項工作。例如,這可能是更改其賬戶上的電子郵件地址,更改密碼或進行資金轉賬。根據(jù)操作的性質,攻擊者可能能夠完全控制用戶的賬號。如果受感染的用戶在應用程序中具有特權角色,那么攻擊者可能能夠完全控制應用程序的所有數(shù)據(jù)和功能。
CSRF 是如何工作的?
要使 CSRF 攻擊稱為可能,必須具備三個關鍵條件:
一個相關的動作。應用程序中存在攻擊者有理由誘導的操作。這可能是特權操作(例如修改其他用戶的權限)或對用戶特定數(shù)據(jù)的任何動作(例如更改用戶自己的密碼)。
基于 Cookie 的會話處理。執(zhí)行該操作涉及發(fā)出一個或多個HTTP請求,并且應用程序僅依賴會話 cookie 來識別發(fā)出請求的用戶。沒有其他機制可用于跟蹤會話或驗證用戶請求。
沒有不可預測的請求參數(shù)。執(zhí)行該操作的請求不包含攻擊者無法確定或猜測其值的任何參數(shù)。例如,當導致用戶更改密碼時,如果攻擊者需要知道現(xiàn)有密碼的值,則該功能不會受到攻擊。
例如,假設一個應用程序包含一個允許用戶更改其賬戶上的電子郵件地址的功能。當用戶執(zhí)行此操作時,他們會發(fā)出如下 HTTP 請求:
POST /email/change HTTP/1.1
Host: vulnerable-website.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 30
Cookie: session=yvthwsztyeQkAPzeQ5gHgTvlyxHfsAfE
email=wiener@normal-user.com
這符合 CSRF 所需的條件:
攻擊者都更改用戶賬戶上的電子郵件地址的操作很感興趣。執(zhí)行此操作后,攻擊者通常能夠觸發(fā)密碼重置并完全控制用戶的賬戶。
應用程序使用會話 cookie 來識別發(fā)出請求的用戶。沒有其他令牌或機制來跟蹤用戶會話。
攻擊者可以輕松確定執(zhí)行操作所需的請求參數(shù)的值。
有了這些條件,攻擊者就可以構建一個包含以下HTML的網(wǎng)頁:
<html>
<body>
<form action="https://vulnerable-website.com/email/change" method="POST">
<input type="hidden" name="email" value="pwned@evil-user.net" />
</form>
<script>
document.forms[0].submit();
</script>
</body>
</html>
如果受害者用戶訪問攻擊者的網(wǎng)頁,將會發(fā)送以下情況:
攻擊者的頁面將觸發(fā)對易受攻擊者的網(wǎng)站的HTTP 請求。
如果用戶登錄到易受攻擊的網(wǎng)站,他們的瀏覽器將自動在請求中包含他們的會話 cookie (假設未使用SameSite cookie)。
易受攻擊的網(wǎng)站將以正常的方式處理請求,將其為由受害者用戶發(fā)出,并更改電子郵件地址。
備注
盡管 CSRF 通常與基于 cookie 的會話處理有關,但它也出現(xiàn)在應用程序自動將一些用戶憑據(jù)添加到請求的其他上下文中,例如 HTTP 基本身份驗證和基于證書的身份驗證。
使用Burp Suite 插件 構建 CSRF 攻擊
手動創(chuàng)建 CSRF 漏洞利用所需的 HTML 可能很麻煩,特別是在所需的請求包含大量參數(shù)或請求中有其他怪癖的情況下。構建 CSRF 漏洞利用的最簡單方法是使用內置于Burp Suite Professional的CSRF PoC 生成器:
在 Burp Suite Professional 中的任意位置選擇您要測試或利用的請求。
• 從右鍵單擊上下文菜單中,選擇參與工具/生成 CSRF PoC。
• Burp Suite 將生成一些 HTML 來觸發(fā)選定的請求(減去 cookie,它將由受害者的瀏覽器自動添加)。
• 您可以調整 CSRF PoC 生成器中的各種選項,以微調攻擊的各個方面。您可能需要在一些不尋常的情況下執(zhí)行此操作以處理請求的古怪功能。
• 將生成的 HTML 復制到網(wǎng)頁中,在登錄到易受攻擊網(wǎng)站的瀏覽器中查看,并測試是否成功發(fā)出了預期的請求以及是否發(fā)生了所需的操作。
CSRF 攻擊條件及與XSS區(qū)別
CSRF 與XSS 區(qū)別:
XSS: 存在XSS漏洞 ——> 構造 payload ——> 發(fā)送給受害者 ——> 受害者觸發(fā) ——> 攻擊者得到受害者cookie ——> 攻擊者使用受害者權限cookie 登錄系統(tǒng)
CSRF: 存在CSRF漏洞 ——> 構造payload ——> 發(fā)送給受害者 ——> 受害人點擊打開 ——> 受害人執(zhí)行代碼 ——> 受害者完成攻擊(不知情)
CSRF攻擊一種需要兩個條件:
1.登錄受信任的網(wǎng)站,本地生成Cookie;
2.在不注銷A情況下,可以訪問網(wǎng)站B
當然還要另一些方法滿足CSRF攻擊條件,你無法保證以下情況不會發(fā)生:
1.不能保證登錄了一個網(wǎng)站,不再打開另一個頁面并訪問另外的網(wǎng)站。
2.你不能保證你關閉了瀏覽器后,本地Cookie立刻過期,并且登錄的會話未結束。
由此 CSRF 是一種較難防御,又危險極大的漏洞!
常規(guī)測試方法
如何確認一個web系統(tǒng)存在csrf漏洞
1,對目標網(wǎng)站增刪改的地方進行標記,并觀察其邏輯,判斷請求是否可以被偽造。
–比如修改管理員賬號時 ,并不需要驗證舊密碼 ,導致請求容易被偽造;
–比如對于敏感信息的修改并沒有使用安全的token驗證,導致請求容易被偽造;
2.確認憑證的有效期(這個問題會提高CSRF被利用的概率)
—雖然退出或者關閉了瀏覽器,但cookie仍然有效,或者session并沒有及時過期,導致CSRF攻擊變的簡單
CSRF是借用戶的權限完成攻擊,攻擊者并沒有拿到用戶的權限,而XSS是直接盜取了用戶的權限,然后實施破壞。
如何確認一個web系統(tǒng)存在CSRF漏洞
1.對目標網(wǎng)站增刪改的地方進行標記,并觀察其邏輯,判斷請求是否可以被偽造
確認憑證的有效期(這個問題會提高CSRF被利用的概率)
CSRF(get/post)實驗演示和解析
CSRFget
我們假設我們是Lucy,登陸網(wǎng)站修改信息。
我們點擊修改信息并提交,修改成功。我們打開burp查看抓到的數(shù)據(jù)包
這是我們的請求:GET/vul/csrf/csrfget/csrf_get_edit.phpsex=5&phonenum=54151&add=411&email=www&submit=submit
我們并沒有看到CSRF的token,說明并沒有防CSRF的措施。
修改get請求,將地址411修改為shanxi
跨站請求及跨站請求偽造(CSRF)
繞過csrf校驗:
1.刪除CSRF令牌,不校驗。
2.通過變換請求,如POST更換GET,但在使用GET方法時跳過驗證。(變換請求方法)
3.應用程序在令牌存在時驗證令牌,但如果省略令牌則跳過驗證。(刪除csrf參數(shù))
4.令牌不綁定用戶會話(用戶加載時獲取csrf token,替換用戶token)
5.csrf cookie和csrf令牌綁定(替換攻擊者的csrf cookie和csrf令牌)
《借刀殺人》
CSRF 構造/發(fā)布請求,已經(jīng)讓用戶在事先不知道的情況下,讓cookie送出cookie的請求,而不是事發(fā)先發(fā)送給用戶的”HTTP 請求”。
CSRF類型
【危害2】漏洞聯(lián)合——CSRF漏洞使self-XSS漏洞“變廢為寶”
存在self-XSS直接漏洞和CSRF漏洞,如果利用self-XSS漏洞則受害者只是自己,如何攻擊自己以外的目標?
目標——通過利用CSRF漏洞,使XSSpayload能夠攻擊自己以外的目標
【危害3】利用CSRF漏洞發(fā)出GET請求
漏洞影響
CSRF 攻擊利用受害者的身份進行操作場景
漏洞聯(lián)合(XSS+CSRF)
某某通過前臺布局者通過提交提交A登錄管理后臺查看數(shù)據(jù)管理員xssPayload(漏洞1利用成功但這是某項攻擊事件的有效權限后cookie過渡將無法在后臺登錄)
在后臺有一個配置“網(wǎng)站名稱”的選項存在存儲類型xss漏洞(但普通漏洞2僅前臺用戶會觸發(fā)管理后臺并不會觸發(fā))
為了 web 后臺的權限維度構造 CSRF 請求并利用漏洞 2 使每個普通用戶都可以提交漏洞 1 的 xssPayload(也可以設置一定的隨時性部分用戶也可以提交)
管理員日常登錄后臺查看數(shù)據(jù)會像他第一次觸發(fā)漏洞1那樣觸發(fā)。
【社交節(jié)點蠕蟲】 - 如果向好友發(fā)送消息的HTTP請求中沒有設置CSRF-token請求頭可結合XSS則可構造出XSS+CSRF蠕蟲影響極大。
【拒絕服務】 - 如果通過前臺構造xssPayload提交成功打到了管理后臺且管理員注銷動作無CSRF防御機制可構造payload使管理員一登錄則注銷。
【網(wǎng)絡后臺權限維度】
網(wǎng)絡場景測試技巧
請求相同重放 - 智能識別令牌是否正確滿足設計:token動態(tài)生成 token會被后端驗證且只能被驗證一次 經(jīng)過后端驗證后的token立即失效
修改令牌值 - 如修改請求正文并發(fā)送請求,查看響應正文是否和正常請求的響應正文相同
刪除令牌值 - 如修改請求正文para1=aaa&token=
并發(fā)送請求,查看響應正文是否和正常請求的響應正文相同
完全刪除令牌參數(shù) - 如修改請求正文為para1=aaa
并發(fā)送請求,查看響應正文是否和正常請求的響應正文相同
HTTP 方法可以由 POST 正確轉換為請求method
,如果可以為 GET 方法
瀏覽器的Cookie策略
若能知道瀏覽器的cookie策略,就會對CSRF的原理與攻擊方式會有更深的理解。
瀏覽器所持有的cookie分成兩種,一種是Session Cookie
,叫做臨時Cookie
,一種是Third-party Cookie
,叫做本地Cookie,也叫做第三方Cookie。
他們之間的區(qū)別在于本地Cookie
是服務器在Set-Cookie時設置了指定的Expire
時間,只有到了制定的Expire
之后,本地Cookie才會失效,所以這種Cookie保存在本地。
而臨時Cookie則沒用綁定Expire
,所以當瀏覽器關閉后,臨時Cookie也就會失效了,所以這種臨時Cookie保存在瀏覽器中。
在瀏覽網(wǎng)站的過程中,如果一個網(wǎng)站設置了臨時Cookie
, 那么在瀏覽器的運行過程中,即使瀏覽器打開了新的網(wǎng)頁,臨時Cookie
也是有效的。
第三方Cookie
是什么:如果我們訪問http://www.a.com
,那么http://www.a.com
就是第一方,如果我們在http://www.a.com
的頁面中,在去訪問http://www.b.com
,那么http://www.b.com
就是第三方。
如果有這么一種情況,瀏覽器從一個域的頁面中,想要加載另一個域的資源,由于安全原因,一些網(wǎng)絡站點會停止本地Cookie
即第三方Cookie的
發(fā)送。就是說,我們已經(jīng)獲得了http://www.b.com
的cookie值,當我們在http://www.a.com
頁面訪問包含在http://www.a.com
頁面中的http://www.b.com
的鏈接時,仍然不會把之前獲得的http://www.b.com
的cookie值發(fā)送過去
但是這里也是有一個前提的,就是http://a.com
頁面包含在http://a.com
頁面中的http://www.b.com
的鏈接時,仍然不會把之前獲得的http://www.b.com
的cookie值發(fā)過去。
但是這里也是有一個前提的,就是http://www.a.com頁面中的http://www.b.com包含在<iframe>, <img>, <script> , <link> 等標簽中,因為這些標簽在IE中,是禁止瀏覽器向這些標簽中發(fā)送第三方cookie的。
當然,并不是所有的瀏覽器都會禁止,比如火狐瀏覽器,就默認支持發(fā)送第三方cookie。
所以至少對于IE瀏覽器,攻擊者需要精心構造攻擊環(huán)境,比如可以先誘使用戶在當前瀏覽器中先訪問目標站點,使得session cookie有效,然后嘗試CSRF。
P3P頭的副作用
盡管對于有些CSRF來說,并不是很需要cookie的,但大部分的敏感信息或重要操作都躲藏在認證之后,因此瀏覽器攔截第三方cookie的發(fā)送,一定程度上還是降低了CSRF的威力,可是P3P頭的出現(xiàn),使得一切復雜起來。
P3P Header 是W3C制定的一項關于隱私的標準,全稱是The Platform for Privacy Preferences.
如果網(wǎng)站返回給瀏覽器的HTTP頭部中包含有PHP3頭,則在某種程度上來說,他會允許瀏覽器發(fā)送第三方cookie,即使是在上文所描述的IE瀏覽器<iframe>
、<input>
也將不在攔截第三方cookie的發(fā)送。
比如存在www.a.com和www.b.com兩個域,在www.b上存在一個頁面,他是包含www.a.com的一個iframe。
http://www.b.com
的內容為<iframe width=20 height=30 src=http://www.a.com/test.php></iframe>
然后http://www.a.com/test.php
是對a.com域設置cookie的頁面,其內容為<?php header("set-cookie:test=axis;path=/")?>
總之這個頁面就是為www.a.com設置cookie。當我們在http://www.b.com
這個頁面時,點擊包含www.a.com的頁面,那么就會轉到http://www.a.com/test.php
嘗試設置cookie,所以瀏覽器會收到一個cookie。然而等之后,我們在去點擊這個點擊包含www.a.com的頁面,如果上次點擊設置cookie成功,那么這次點擊就會自動發(fā)送剛才收到的cookie,可是由于cookie跨域限制,上次點擊沒有設置成功cookie,所以這次訪問,還是再次接收到和上次一樣的cookie,說明上次的cookie并沒有發(fā)送出去。
但是如果加入了P3P頭之后,這種情況就會發(fā)生改變,第二次點擊那個頁面就會發(fā)出第一次收到的cookie值。
因為P3P頭在網(wǎng)站中的廣泛應用,所以在CSRF的防御,不能僅依賴于瀏覽器對第三方cookie的防御策略,應該從長計議。
CSRF的防御
常見CSRF防范措施
增加token驗證(常用多點做法 ):
1.對關鍵操作增加token參數(shù),token值必須隨機,每次都不一樣;
關于安全的會話管理(避免會話被利用):
1.不要在客戶端端保存敏感信息(比如身份認證信息);
2.測試直接關閉,退出時,的會話過期機制;
3.設置會話過期機制,比如15分鐘內無操作,則自動登錄超時;
訪問控制安全管理:
1.敏感信息修改時需要對身份進行二次認證,比如修改賬號時,需要判斷舊密碼;
2.敏感信息的修改使用post,而不是get;
3.通過http頭部中的referer來限制原頁面
增加驗證碼:
一般用在登錄(防暴力破解),也可以用在其他重要信息操作的表單中(需要考慮可用性)
簽名與時間戳防護處理流程
Token產(chǎn)生
1.Token構成
為了防止CSRF攻擊,Token要求不能重復,需要含有時間戳信息,簽名信息。
下面的圖描述了一個token的數(shù)據(jù)構成:
Token的數(shù)據(jù)結構。
token由三部分組成:
a). 消息[msg]:而msg本身也有兩部分組成:一部分:隨機字符串,過期時間戳。
b). 分割符[separator]:用于分隔msg部分與加密后生成的signature簽名部分,這里用的是”.“
c). 簽名[signature]:signature。signature簽名,是對“msg消息”用特定算法進行加密后的串。
CSRF攻擊常規(guī)防護
1.只使用JSON API,使用Javascript發(fā)起AJAX請求是限制跨域的,并不能通過簡單的表單來發(fā)送JSON,所以,通過只接收JSON可以很大可能避免CSRF攻擊。
2.驗證HTTP Referer字段,根據(jù) HTTP 協(xié)議,在 HTTP 頭中有一個字段叫Referer,它記錄了該HTTP 請求的來源地址。在通常情況下,訪問一個安全受限頁面的請求來自于同一個網(wǎng)站,比如上文用戶User想要在網(wǎng)站W(wǎng)ebA中進行轉賬操作,那么用戶User
3.必須先登錄WebA,然后通過點擊頁面上的按鈕觸發(fā)轉賬事件。
這時該轉賬請求的 Referer 值就會是轉賬按鈕所在的頁面的URL,而如果黑客要對銀行網(wǎng)站實施CSRF攻擊,他只能在他自己的網(wǎng)站構造請求,當用戶User通過黑客的網(wǎng)站發(fā)送請求到WebA時,該請求的Referer 是指向黑客自己的網(wǎng)站。
因此,要防御 CSRF 攻擊,網(wǎng)站W(wǎng)ebA只需要對于每一個轉賬請求其Referer值,如果是以網(wǎng)站webA的網(wǎng)址開頭的域名,則說明該請求時來自WebA自己多點請求,時合法的,如果 Referer 是其他網(wǎng)址的話,則有可能是黑客的CSRF攻擊,拒絕該請求。
4.在請求地址添加token驗證
CSRF 攻擊之所以能偶成功,是因為黑客可以完全偽造用戶的請求,該請求中所有的用戶驗證信息都是存在于cookie中,因此黑客可以在不知道這些驗證信息的情況下直接利用用戶自己的cookie來通過安全驗證。要抵御CSRF,關鍵在于請求中放入黑客無所不能偽造的信息,并且該信息存在于cookie之中。可以在HTTP請求中以參數(shù)的形式加入一個隨機產(chǎn)生的token,并在服務器端建立一個攔截器來驗證這個token,如果請求中沒有token或者token內容不正確,則認為可能是CSRF攻擊而拒絕該請求。
這種方法要比檢查Referer 要安全一些,token 可以在用戶登錄參生并放于 session 之中,然后再每次請求時把token從session中拿出,與請求中的token進行比對。
驗證碼
驗證碼是對抗CSRF最簡單,最有效的防御方法。
CSRF攻擊的過程,往往是在用戶不知情的情況下,構造網(wǎng)絡請求。而驗證碼,則強制用戶必須與應用進行交互,才能完成最終請求。因此在通常情況下,驗證碼的存在能很好地遏制CSRF。
但是驗證碼并不方便,對用戶體驗并不友好,所以他只能作為一種備選策略存在,無法作為主方法。
Referer Check
Referer Check即參考檢查,其實他在互聯(lián)網(wǎng)中最常見的應用應該是防止圖片盜鏈
,但是他也可以用來檢查請求是否存在合法的源
。
常見的互聯(lián)網(wǎng)應用,頁面與頁面之間都具有一定的邏輯關系,這就使得每一個正常請求的Referer具有一定的規(guī)律。
比如一個‘論壇發(fā)帖’的操作,在正常情況下,需要先登錄到用戶后臺,或者訪問有發(fā)帖功能的頁面。在提交發(fā)帖的表單時,Referer的值必然是發(fā)帖表單所在的頁面,但如果Referer的值不是這個頁面,甚至不是發(fā)帖網(wǎng)站的域,那么極大可能就是CSRF攻擊。
但是Referer Check的缺陷也很明顯,服務器并不是任何時候都能獲取到Referer,很多用戶出于隱私的考慮,限制了Referer的發(fā)送,而對于瀏覽器也是同理,某些情況下,比如從HTTPS跳轉到HTTP,瀏覽器也不會發(fā)送Referer。
所以,Referer Check其實也不是一個特別好的防御手段,只能作為防御的備用策略。
使用token
CSRF的本質
在講token之前,我們需要知道,CSRF之所以能夠攻擊成功,除了利用cookie,更重要
攻擊者只有預測出URL的所有參數(shù)與參數(shù)值,才能成功構造一個偽造的請求,反之,則攻擊不成功
基于此,有一個解決方案,把參數(shù)加密,或者使用一些隨機數(shù),讓攻擊者無法猜測到正確的參數(shù)。
比如,一個刪除的url是:
http://www.a.com/require?username=123&item=123
但是可以通過參數(shù)加密,使得刪除的url值為:
http://www.a.com/require?username=1f69f7d19e9455605f6d941de5257ee1&item=123
這樣就無法猜測出username的值,從而無法實施攻擊
但這種方法存在的缺陷是,加密后的URL非常難讀,對用戶不友好,其次,如果每次URL值都發(fā)生變化,還會使得URL無法被用戶收藏。所以這種方法有了一個晉升版,就是構造token。
Token的特點
1、Token值必須是隨機的,可以通過使用安全的隨機數(shù)生成算法實現(xiàn)
2、Token值是私密的,不能被第三方知曉。他可以存放在服務器的cookie中,也可以存放在瀏覽器的cookie中。但唯獨Token值不能直接放在URL中,因為直接放在URL中,可能也會導致瀏覽器通過Refer得方式泄露。
比如下面這個頁面
http://www.a.com/manage?username=abc&token={隨機值}
如果在這個頁面中包含了一個攻擊者能指定地址的圖片,比如
<img src="http://www.b.com/a">
那么如果點擊這個圖片,那么可能就會出現(xiàn)http://www.a.com/manage?username=abc&token={隨機值}
作為HTTP請求的Referer發(fā)送到http://www.b.com
這個域中,從而導致Token的泄露。
因此在使用Token時,盡量將其放在表單中,把敏感操作由GET改成POST,以表單的形式提交,避免Token泄露
3、Token需要同時放在表單和session中。在提交請求時,服務器只需要驗證表單中的Token與用戶session(或者cookie)中的Token值是否相同,如果一致,則是合法請求,如果不一致,或者有一個為空,則請求不合法,就可能是CSRF攻擊
CSRF 漏洞防御策略
再服務器端防御CSRF攻擊主要有四種策略:
根據(jù)HTTP協(xié)議,在HTTP頭中有一個字段叫Referer,它記錄了該HTTP請求的來源地址。在通常情況下,訪問一個安全受限頁面的請求必須來自于同一個網(wǎng)站。比如某銀行的轉賬是通過用戶訪問http://bank.test/test?page=10&userID=101&money=10000頁面完成,用戶必須先登錄bank.test,然后通過點擊頁面上的按鈕來觸發(fā)轉賬事件。當用戶提交請求時,該轉賬請求的Referer值就會是轉賬按鈕所在頁面的URL(本例中,通常是以bank. test域名開頭的地址)。而如果攻擊者要對銀行網(wǎng)站實施CSRF攻擊,他只能在自己的網(wǎng)站構造請求,當用戶通過攻擊者的網(wǎng)站發(fā)送請求到銀行時,該請求的Referer是指向攻擊者的網(wǎng)站。因此,要防御CSRF攻擊,銀行網(wǎng)站只需要對于每一個轉賬請求驗證其Referer值,如果是以bank. test開頭的域名,則說明該請求是來自銀行網(wǎng)站自己的請求,是合法的。如果Referer是其他網(wǎng)站的話,就有可能是CSRF攻擊,則拒絕該請求。
• 在請求地址中添加token并驗證
CSRF攻擊之所以能夠成功,是因為攻擊者可以偽造用戶的請求,該請求中所有的用戶驗證信息都存在于Cookie中,因此攻擊者可以在不知道這些驗證信息的情況下直接利用用戶自己的Cookie來通過安全驗證。由此可知,抵御CSRF攻擊的關鍵在于:在請求中放入攻擊者所不能偽造的信息,并且該信息不存在于Cookie之中。鑒于此,系統(tǒng)開發(fā)者可以在HTTP請求中以參數(shù)的形式加入一個隨機產(chǎn)生的token,并在服務器端建立一個攔截器來驗證這個token,如果請求中沒有token或者token內容不正確,則認為可能是CSRF攻擊而拒絕該請求。
• 在HTTP頭中自定義屬性并驗證
自定義屬性的方法也是使用token并進行驗證,和前一種方法不同的是,這里并不是把token以參數(shù)的形式置于HTTP請求之中,而是把它放到HTTP頭中自定義的屬性里。通過XMLHttpRequest這個類,可以一次性給所有該類請求加上csrftoken這個HTTP頭屬性,并把token值放入其中。這樣解決了前一種方法在請求中加入token的不便,同時,通過這個類請求的地址不會被記錄到瀏覽器的地址欄,也不用擔心token會通過Referer泄露到其他網(wǎng)站。
Token 防御 CSRF Example
針對使用token 防御 CSRF 攻擊,我這里做一個簡單的介紹:
1.要使Token對攻擊者來說難以偽造,我們可以使用偽隨機數(shù)生成器來構造它 稱為Token 隨機數(shù),好似在沒一個參數(shù)中都加入一個隨機的Token來此防御,然后把它放到服務器端的session里,并將Token發(fā)給用戶(注意并沒有保存在cookie中);
2.當用戶提交請求時,服務器攔截器將POST請求中的Token提取出來,與session中的Token進行比對,相等即執(zhí)行下一步操作。(這一部分就非常有必要!否則添加了防御的CSRF也是可以繞過的?。?/p>
具體代碼:
# 生成 token
session_start();
function set_token(){
$_SESSION['token'] = md5(time()+rand(1,5000));
}
# 使用 token 做驗證
function check_token(){
if(isset($_POST['token'])&&$_POST['token'] === $_SESSION['token'])
{
return ture;
}
else
{
return false;
}
}
可以看到,同時驗證了cookie中的sessionid與POST中的Token。
### SDL - 防御與修復方案
* web框架 - 啟動框架中成熟的CSRF防御功能
* 自定義HTTP請求頭(Custom Request Headers)
* 如使用`X-CSRF-token:xxxx`標明CSRF_TOKEN的值(即使CSRF利用成功發(fā)出了攜帶Cookie的HTTP請求 但后端判斷`X-CSRF-token`不存在則拒絕請求)
* One-time Token
* 如每次提交表單都包含字段`Token=xxxx`且每次值不同 后端可校驗是否正確
* `Set-Cookie`使用`SameSite`屬性
* 后端Response Header`Set-Cookie`中設置`SameSite`屬性(由Google引入瀏覽器 用于緩解CSRF攻擊),`SameSite`屬性有3種值:
* `Strict`嚴格
* 例如 域b.com的Response Header有`Set-Cookie: admin_cookie_strict=xxx; SameSite=Strict`,瀏覽器中會保存這一Cookie字段`admin_cookie_strict=xxx`,但由于`SameSite=Strict`為**嚴格**,所以瀏覽器對(非b.com域下發(fā)起的)訪問b.com的**任何跨域請求**都不允許攜帶這一Cookie字段`admin_cookie=xxx`,所以可以防御CSRF攻擊。比如從域a.com下構造并發(fā)出跨域請求訪問b.com(嘗試CSRF),絕對不會攜帶關鍵的cookie,從而b.com后端鑒權失敗,CSRF攻擊失敗
* `Lax`寬松 - 沒有`SameSite`屬性的cookie被瀏覽器默認為`SameSite=Lax`
* 例如 域b.com的Response Header有`Set-Cookie: admin_cookie_lax=xxx; SameSite=Lax`,瀏覽器中會保存這一Cookie字段`admin_cookie_lax=xxx`,但由于`SameSite=Strict`為**寬松**,所以瀏覽器對(非b.com域下發(fā)起的)訪問b.com的**多種跨域請求**都不允許攜帶這一Cookie字段,只有以下3種方式(任何一種),才能夠攜帶b.com的cookie`admin_cookie_lax=xxx`
* 非同域下的a標簽 `<a href="http://b.com"></a>`
* 非同域下的GET表單 `<form method="GET" action="http://b.com/formdemo">`
* 非同域下的link標簽 `<link rel="prerender" href="http://b.com"/>`
* `None`無
* `SameSite=None`必須同時指定`Secure`,例如`Set-Cookie: session_none=abc123; SameSite=None; Secure`
* 二次驗證 - 安全但影響用戶體驗(適用于僅對敏感功能處進行防御)
* CAPTCHA 增加驗證碼機制
* 再次輸入密碼
* 手機驗證碼
* (不推薦)通過`Referer/Origin`校驗來源域名
* 缺陷1.只能防御從"不被信任"的域發(fā)起的偽造的http請求(如果 **父、子、兄弟域名** 或 **CORS中被信任的域名** 有XSS漏洞 配合構造一個偽造請求 此時referer和Origin的值都是被信任的域 此時“校驗來源域名”無法防御)
* 缺陷2.正常業(yè)務如果有302跳轉 不攜帶Origin
參考OWASP [Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.md](https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.md)
文章來自于互聯(lián)網(wǎng),只做交流分享,如有侵權請聯(lián)系刪除!原文鏈接:https://www.kanxue.com/chm.htm?id=18479&pid=node1001515
該文章在 2023/12/7 11:18:32 編輯過