今天北哥就給大家普及下csrf是啥?如果你已經知道了可以直接拉文章到底部點個贊。
CSRF(Cross-site request forgery跨站請求偽造)是一種對網站的惡意利用,在 2007 年曾被列為互聯網 20 大安全隱患之一。
關于CSRF,要從一個故事開始~
老王丟錢事件這個故事要從程序員老王丟了1萬塊錢說起,總之是進了小偷,找回無果。丟錢后的老王一直在思考,錢是怎么丟的、為何丟錢、為何是我丟錢~~
后來老王出現了嚴重的心理問題,他決定報復社會。
老王首先研究了網銀系統,他發現轉賬是通過GET形式
http://bank.abc.com/withdraw?account=liuxiaoer amount=1000 to=abei
這意思就是說將 liuxiaoer 的1000元錢轉給abei,當然當請求到達銀行服務器后,程序會驗證該請求是否來自合法的session并且該session的用戶就是 liuxiaoer 并且已經登錄。
老王自己也有一個銀行賬號 wang2,他嘗試登錄并且通過瀏覽器發送請求給銀行,代碼如下
http://bank.abc.com/withdraw?account=liuxiaoer amount=1000 to=wang2
失敗了~因為當前登錄賬號是老王自己,發送請求后服務器發現session所屬用戶wang2和account=liuxiaoer并不是一個人,因此被拒絕。
也就是說這個操作必須是 liuxiaoer 自己才可以,復仇的力量是可怕的,老王通過facebook層層找到了 liuxiaoer 就是快遞員老劉的銀行賬號。
于是一個偉大的計劃誕生了,老王的計劃是這樣的。
1、首先做一個網頁,在網頁中加入如下代碼
src= http://bank.abc.com/withdraw?account=liuxiaoer amount=1000 to=wang2
然后通過各種情景讓老劉(liuxiaoer)訪問了此網頁。
2、當老劉(liuxiaoer)訪問此網頁后,上面的請求會被發送到銀行,此刻還會帶著老劉(liuxiaoer)自己的瀏覽器cookie信息,當然這樣一般也不會成功,因為銀行服務器發現老劉(liuxiaoer)并不在登錄狀態。
3、老王想了一個招,他在淘寶找了一個灰色商人老李,讓他通過種種方法,總之讓老劉(liuxiaoer)通過瀏覽器給老李轉了一次款。
4、就在第三步操作的2分鐘內,老王成功讓老劉(liuxiaoer)再一次訪問了自己做的網頁,你知道的,此刻老劉(liuxiaoer)在銀行的session還沒有過期,老王網頁給銀行服務器發送請求后,驗證通過,打款成功。
5、老王收到了款,老劉(liuxiaoer)并不知道這一切,對于銀行來說這是一筆在正常不過的轉賬。
這就是CSRF攻擊,瀏覽器無法攔截。
CSRF攻擊特點基于上面血淋淋的故事,我們總結下CSRF攻擊的幾個特點。
黑客借助于受害者的cookie等瀏覽器信息騙取服務器新人,黑客并拿不到cookie等。
由于瀏覽器同源策略,黑客無法拿到攻擊的響應結果,能做的只是發起請求,你是否還記得很多釣魚網站都模擬了登錄框么?
CSRF攻擊主要是發送修改數據請求。
CSRF防御對象因此我們要保護的是所有能引起數據變化的客戶端請求,比如新建、更新和刪除。
CSRF防御方案基于CSRF攻擊特點,在業界目前防御 CSRF 攻擊主要有三種策略:
驗證 HTTP Referer 字段;
在請求地址中添加 token 并驗證;
在 HTTP 頭中自定義屬性并驗證。
HEEP Referer在http請求的時候,頭部有一個叫做Referer的字段,該字段記錄本次請求的來源地址。因此服務器端可以通過此字段是否為同一個域名來判斷請求是否合法,因為客戶自己做的網頁發起的請求,其Referer為黑客網站。
這種方法最簡單,并且不需要修改業務代碼,我們只需要對到達服務器的每個請求做一次攔截分析即可。
但是此方法的缺點也是明顯的,因為Referer的值是瀏覽器的,雖然HTTP協議不允許去修改,但是如果瀏覽器自身存在漏洞,那么就有可能導致Referer被人工設置,不安全。
比如IE6,就可以通過方法篡改Referer值。
就算是最新的瀏覽器此方法也不是絕對可用的,這涉及了用戶的隱私,很多用戶會設置瀏覽器不提供Referer,因此服務器在得不到Referer的情況下不能貿然的決絕服務,有可能這是一個合法請求。
添加TokenCSRF攻擊之所以能成功,是因為黑客完全偽造了一次用戶的正常請求(這也是瀏覽器無法攔截的原因),并且cookie信息就是用戶自己的,那么我們如果在請求中放入一些黑客無法去偽造的信息(不存在與cookie中),不就可以抵御了么!
比如在請求前生成一個token放到session中,當請求發生時,將token從session拿出來和請求提交過來的token進行對比,如果相等則認證通過,否則拒絕。token時刻在變化,黑客無法去偽造。
針對于不同類型的請求一般方案是
GET 放到url中,比如http://url?csrftoken=xxxx
POST 放到表單的隱藏域 input type=”hidden” name=”csrftoken” html' target='_blank'>value=”xxxx”/
對于GET請求,這里有一點要說明,在一個網站中請求的url很多,一般情況我們是通過js對dom的所有節點進行遍歷,發現a鏈接就在其href中增加token。
這里存在一個問題,比如黑客將自己網站的鏈接發到了要攻擊頁面,則黑客網站鏈接后面會有一個token,此刻客戶可以通過編寫自己網站代碼得到這個token,然后用這個token立刻構造表單,發起CSRF攻擊,因此在js遍歷的時候,如果發現不是本站的鏈接,可以不加token。
在HTTP頭部增加屬性這個方法在思路上和上面的token方式一樣,只不過將token放到了HTTP頭部中,不再參數傳遞,通過XMLHttpRequest類可以一次性的給所有請求加上csrftoken這個HTTP頭屬性并設置值。
這種方法適合上面批量添加token不方便的情況,一次性操作,不過局限性也比較大,XMLHttpRequest請求通常用在ajax方法中,并非所有請求都適合。
Yii2首先要說的是每種CSRF防范措施都有其弊端,無論你的防范多么嚴密,黑客擁有更多的攻擊手段,因此在重要邏輯上(必須寫入和刪除)必須非常小心,接下來我們把yii2框架在csrf上的部署說一下。
我們以yii2.0.14為解說版本。
在CSRF這塊,yii2框架采取了HTTP頭部和參數token并行的方式,針對于每個請求,在beforeAction都會做一次判斷,如下
// vendor/yiisoft/yii2/web/Controller.phppublic function beforeAction($action) { if (parent::beforeAction($action)) { if ($this- enableCsrfValidation Yii::$app- getErrorHandler()- exception === null !Yii::$app- getRequest()- validateCsrfToken()) { throw new BadRequestHttpException(Yii::t( yii , Unable to verify your data submission. return true; return false;}
如果我們沒有設置 enableCsrfValidation 為false,并且沒有報錯,則會進行csrf驗證,核心方法就是
Yii::$app- getRequest()- validateCsrfToken()
該方法存在于 vendor/yiisoft/yii2/web/Request.php 中,我們看一看它。
public function validateCsrfToken($clientSuppliedToken = null) { // 省略上面代碼 return $this- validateCsrfTokenInternal($this- getBodyParam($this- csrfParam), $trueToken) || $this- validateCsrfTokenInternal($this- getCsrfTokenFromHeader(), $trueToken);}
validateCsrfToken函數代碼我們只需要看最后的返回,getBodyParam或getCsrfTokenFromHeader方法得到的token,只要有一種驗證通過,就認為合法。
以上是整體的思路,為了讓你看的更清晰,我畫一個圖并增加一些名詞解釋。
以上是yii2的csrf策略部署,當然我還是推薦你使用 xdebug等調試工具 一步一步看看這個過程。
最后我在把上圖的關鍵函數進行說明
generateCsrfToken() 該函數生成token并存到cookie或session中,該值不會隨頁面刷新而變化,它更多充當鑰匙的作用,根絕它生成具體的csrfToken。
getCsrfToken() 生成具體的csrfToken,就是你在表單隱藏域中看到的那個值,這個值將來會傳到服務器和真實的csrfToken進行對比,驗證是否合法。
validateCsrfToken() 進行合法性驗證,該函數得到一個真實的csrfToken然后和客戶端上傳來的csrfToken進行對比。
以上就是本文的全部內容,希望對大家的學習有所幫助,更多相關內容請關注PHP !
相關推薦:
如何在yii2-wx中使用try_catch
關于Yii2中GridView的用法總結
以上就是yii2對csrf攻擊的防范措施的詳細內容,PHP教程
鄭重聲明:本文版權歸原作者所有,轉載文章僅為傳播更多信息之目的,如作者信息標記有誤,請第一時間聯系我們修改或刪除,多謝。
新聞熱點
疑難解答