CSRF 1 (转)
一.CSRF是什么?
CSRF(Cross-site request forgery),中文名稱:跨站請求偽造,也被稱為:one click attack/session riding,縮寫為:CSRF/XSRF。
二.CSRF可以做什么?
你這可以這么理解CSRF攻擊:攻擊者盜用了你的身份,以你的名義發(fā)送惡意請求。CSRF能夠做的事情包括:以你名義發(fā)送郵件,發(fā)消息,盜取你的賬號,甚至于購買商品,虛擬貨幣轉(zhuǎn)賬......造成的問題包括:個人隱私泄露以及財產(chǎn)安全。
三.CSRF的原理
要完成一次CSRF攻擊,受害者必須依次完成兩個步驟:
1.登錄受信任網(wǎng)站A,并在本地生成Cookie。
2.在不登出A的情況下,訪問危險網(wǎng)站B。
示例1:
銀行網(wǎng)站A,它以GET請求來完成銀行轉(zhuǎn)賬的操作,如:http://www.mybank.com/Transfer.php?toBankId=11&money=1000
危險網(wǎng)站B,它里面有一段HTML的代碼如下:<img?src=http://www.mybank.com/Transfer.php?toBankId=11&money=1000>
首先,你登錄了銀行網(wǎng)站A,然后訪問危險網(wǎng)站B,噢,這時你會發(fā)現(xiàn)你的銀行賬戶少了1000塊......為什么會這樣呢?原因是銀行網(wǎng)站A違反了HTTP規(guī)范,使用GET請求更新資源。
示例2:
為了杜絕上面的問題,銀行決定改用POST請求完成轉(zhuǎn)賬操作。
銀行網(wǎng)站A的WEB表單如下:
<form?action="Transfer.php"?method="POST">
<p>ToBankId:?<input?type="text"?name="toBankId"?/></p>
<p>Money:?<input?type="text"?name="money"?/></p>
<p><input?type="submit"?value="Transfer"?/></p>
</form>
后臺處理頁面Transfer.php如下:
<?php
session_start();
if?(isset($_REQUEST['toBankId']?&& isset($_REQUEST['money']))
{
??? buy_stocks($_REQUEST['toBankId'], $_REQUEST['money']);
}
?>
危險網(wǎng)站B,仍然只是包含那句HTML代碼:
<img?src=http://www.mybank.com/Transfer.php?toBankId=11&money=1000>
,你首先登錄了銀行網(wǎng)站A,然后訪問危險網(wǎng)站B,結(jié)果.....和示例1一樣,你再次沒了1000塊~T_T,事故的原因是:銀行后臺使用了$_REQUEST去獲取請求的數(shù)據(jù),而$_REQUEST既可以獲取GET請求的數(shù)據(jù),也可以獲取POST請求的數(shù)據(jù),這就造成了在后臺處理程序無法區(qū)分這到底是GET請求的數(shù)據(jù)還是POST請求的數(shù)據(jù)。在PHP中,可以使用$_GET和$_POST分別獲取GET請求和POST請求的數(shù)據(jù)。在JAVA中,用于獲取請求數(shù)據(jù)request一樣存在不能區(qū)分GET請求數(shù)據(jù)和POST數(shù)據(jù)的問題。;
示例3:
經(jīng)過前面2個慘痛的教訓(xùn),銀行決定把獲取請求數(shù)據(jù)的方法也改了,改用$_POST,只獲取POST請求的數(shù)據(jù),后臺處理頁面Transfer.php代碼如下:
<?php
session_start();
if?(isset($_POST['toBankId']?&& isset($_POST['money']))
{
????buy_stocks($_POST['toBankId'], $_POST['money']);
}
?>
<head>
<script?type="text/javascript">
function?steal()
{
?????????? iframe?=?document.frames["steal"];
????? ????? iframe.document.Submit("transfer");
}
</script>
</head>
<body?οnlοad="steal()">
<iframe?name="steal"?display="none">
<form?method="POST"?name="transfer" action="http://www.myBank.com/Transfer.php">
<input?type="hidden"?name="toBankId"?value="11">
<input?type="hidden"?name="money"?value="1000">
</form>
</iframe>
</body>
</html> 如果用戶仍是繼續(xù)上面的操作,很不幸,結(jié)果將會是再次不見1000塊......因為這里危險網(wǎng)站B暗地里發(fā)送了POST請求到銀行! 總結(jié)一下上面3個例子,CSRF主要的攻擊模式基本上是以上的3種,其中以第1,2種最為嚴(yán)重,因為觸發(fā)條件很簡單,一個<img>就可以了,而第3種比較麻煩,需要使用JavaScript,所以使用的機會會比前面的少很多,但無論是哪種情況,只要觸發(fā)了CSRF攻擊,后果都有可能很嚴(yán)重。 理解上面的3種攻擊模式,其實可以看出,CSRF攻擊是源于WEB的隱式身份驗證機制!WEB的身份驗證機制雖然可以保證一個請求是來自于某個用戶的瀏覽器,但卻無法保證該請求是用戶批準(zhǔn)發(fā)送的!
四.CSRF的防御
我總結(jié)了一下看到的資料,CSRF的防御可以從服務(wù)端和客戶端兩方面著手,防御效果是從服務(wù)端著手效果比較好,現(xiàn)在一般的CSRF防御也都在服務(wù)端進行。
1.服務(wù)端進行CSRF防御
服務(wù)端的CSRF方式方法很多樣,但總的思想都是一致的,就是在客戶端頁面增加偽隨機數(shù)。
(1).Cookie Hashing(所有表單都包含同一個偽隨機值):
這可能是最簡單的解決方案了,因為攻擊者不能獲得第三方的Cookie(理論上),所以表單中的數(shù)據(jù)也就構(gòu)造失敗了:>
<?php
//構(gòu)造加密的Cookie信息
$value?=?“DefenseSCRF”;
setcookie(”cookie”,?$value,?time()+3600);
?>
在表單里增加Hash值,以認(rèn)證這確實是用戶發(fā)送的請求。
<?php
$hash?=?md5($_COOKIE['cookie']);
?>
<form?method=”POST”?action=”transfer.php”>
<input?type=”text”?name=”toBankId”>
<input?type=”text”?name=”money”>
<input?type=”hidden”?name=”hash”?value=”<?=$hash;?>”>
<input?type=”submit”?name=”submit”?value=”Submit”>
</form>
然后在服務(wù)器端進行Hash值驗證
?<?php
??????if(isset($_POST['check']))?{
????? ??????$hash?=?md5($_COOKIE['cookie']);
?????????? ?if($_POST['check']?==?$hash)?{
??????????????? doJob();
?????????? }?else?{
//...
?????????? }
????? }?else?{
//...
????? }
???????>
這個方法個人覺得已經(jīng)可以杜絕99%的CSRF攻擊了,那還有1%呢....由于用戶的Cookie很容易由于網(wǎng)站的XSS漏洞而被盜取,這就另外的1%。一般的攻擊者看到有需要算Hash值,基本都會放棄了,某些除外,所以如果需要100%的杜絕,這個不是最好的方法。
?
轉(zhuǎn)載于:https://www.cnblogs.com/lhq8998/p/7295435.html
總結(jié)
以上是生活随笔為你收集整理的CSRF 1 (转)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: day6作业--游戏人生
- 下一篇: ubuntu 12.04解决Broadc