天天看點

CSRF跨站請求僞造Cross-Site Request ForgeryCSRF攻擊場景CSRF請求僞造CSRF防守政策參考

文章目錄

  • Cross-Site Request Forgery
  • CSRF攻擊場景
  • CSRF請求僞造
    • GET
    • POST
    • XMLHttpRequest
  • CSRF防守政策
    • 驗證碼
    • Anti CSRF Token
    • JSON Web Token
  • 參考

Cross-Site Request Forgery

CSRF,Cross-Site Request Forgery,跨站請求僞造,也被稱為: XSRF, One-Click attack, Sea Surf, Session Riding, Cross-Site Reference Forgery, and Hostile Linking。

CSRF是指攻擊者通過某些技術手段欺騙使用者,盜用其已認證的身份去執行一些惡意操作(如修改使用者郵件或密碼,發消息,轉賬和購買商品)。

CSRF漏洞與浏覽器的隐式身份認證機制有關。使用者在目标網頁完成身份認證時,浏覽器會在本地(Cookie)儲存目前會話狀态資訊,當使用者再次發送請求時,浏覽器會自動攜帶該會話Cookie, 伺服器據此判斷請求來自同一使用者(會話),執行請求操作。

這時假如攻擊者成功誘使使用者打開攻擊站點,則可向目标站點發送僞造請求。由于使用者已經認證過,是以浏覽器将自動攜帶之前的會話Id,被通路網站則會認為這是使用者的真實請求而去執行。

跨站是指惡意請求是由攻擊站點發起,而不是使用者一開始通路的可信站點。由于浏覽器同源政策(Same Origin Policy)的限制,攻擊者一般無法在攻擊站點擷取使用者Cookie,而隻能通過僞造請求進行攻擊。

CSRF攻擊場景

典型場景如下:

  • 使用者登入可信站點A
  • 未logout的情況下通路攻擊站點B
  • 攻擊站點B向站點A發送惡意請求

攻擊實作的難點是第二步,即如何讓使用者在通路A的同時剛好打開B。

常見的形式有釣魚郵件、詐騙資訊、浏覽器彈出視窗(浏覽器劫持)、漏洞站點代碼植入等。

比如你在操作網銀時,剛好看到一封銀行發送給你的(釣魚)郵件,或者剛好浏覽器彈出一個你感興趣的新聞,然後你眼疾手快地點選了裡面的連結。

攻擊站點B不一定是惡意站點,可能隻是有漏洞的普通網站,甚至是受歡迎的高流量網站。

B向A發送請求是通過技術手段自動實作。也就是說,當打開網頁時,你就中招了,并不需要任何其他操作。是以盡管使用者登入A的同時正好打開B的幾率不大,但是黑客并不需要做什麼,隻是坐等收錢,因而這肯定也是一種受歡迎的攻擊手段。

另外,大多數人都沒有完成操作就立即登出的良好習慣。

CSRF請求僞造

GET

典型例子如下,

img

的情況下不需要使用者點選連結,打開視窗便自動送出請求。

<a href="http://bank.com/transfer.do?acct=MARIA&amount=100000">View my Pictures!</a>

<img src="http://bank.com/transfer.do?acct=MARIA&amount=100000" width="0" height="0" border="0">
           

是以一般更新操作不要用Get,因為僞造成本太低。

POST

Post實作相對應的代碼如下。

表單當然是不顯示出來的,通常放在隐藏的iframe裡。

<form action="<nowiki>http://bank.com/transfer.do</nowiki>" method="POST">
<input type="hidden" name="acct" value="MARIA"/>
<input type="hidden" name="amount" value="100000"/>
<input type="submit" value="View my pictures"/>
</form>

<body onload="document.forms[0].submit()">
           

XMLHttpRequest

XMLHttpRequest方法受浏覽器同源政策限制,一般不會成功,除非目标站點定義了

Access-Control-Allow-Origin: *

但是,在JavaScript的世界裡,繞過同源政策的代碼卻很容易找到,更不用說各種各樣的浏覽器漏洞了。

<script>
function put() {
	var x = new XMLHttpRequest();
	x.open("PUT","http://bank.com/transfer.do",true);
	x.setRequestHeader("Content-Type", "application/json"); 
	x.send(JSON.stringify({"acct":"BOB", "amount":100})); 
}
</script>
<body onload="put()">
           

CSRF防守政策

由以上分析可知,CSRF攻擊之是以能奏效,主要是因為攻擊者可以成功地僞造一個合法的請求,即目标操作的所有參數都可以被分析出來。

是以防範的政策主要是往請求中加入無法猜測的參數值,比如驗證碼和Token。

驗證碼

驗證碼是最簡單有效的方法,但是因為影響使用者體驗,不能作為主要的解決方案。

Anti CSRF Token

CSRF Token方法與驗證碼類似,隻是不需要使用者幹預。

增加一個随機生成的Token,發送給前端,前端送出表單時包含該Token,在背景驗證,驗證通過才是有效請求。

一個請求送出後,Token即被消耗掉,然後重新生成新Token。是以,也要考慮同時有多個請求時的并發處理問題。

注意:

  • Token要足夠随機,不可預測。
  • Token要注意保密,不能洩露。

比如頁面如果同時有XSS(跨站腳本攻擊)漏洞,則攻擊者完全可以讀出頁面的Token值,再僞造合法的請求,這一過程一般稱為XSRF,與CSRF相差別。

除了加Token,也可以考慮給參數加密,或者驗證通路來源(Referrer)。

JSON Web Token

假如我已經使用了JWT無狀态App設計,還需不需要再引入CSRF Token?

答案是:不需要。

除了不是by request生成,JWT具有CSRF Token相同的特征,因而是安全的。

總的來說,避免使用Cookie進行身份認證,應該已經可以防範大多數的CSRF漏洞。

參考

https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)

《白帽子講Web安全》 —— 吳翰清

CSRF跨站請求僞造Cross-Site Request ForgeryCSRF攻擊場景CSRF請求僞造CSRF防守政策參考

繼續閱讀