搜尋
首頁後端開發php教程yii2對csrf攻擊的防範措施

yii2對csrf攻擊的防範措施

Jul 10, 2018 pm 03:06 PM
csrfyii2

這篇文章主要介紹了關於yii2對csrf攻擊的防範措施,有著一定的參考價值,現在分享給大家,有需要的朋友可以參考一下

今天北哥就給大家普及下csrf是啥?如果你已經知道可以直接拉文章到底部按個讚了。

CSRF(Cross-site request forgery跨站請求偽造)是一種對網站的惡意利用,在2007 年曾被列為互聯網20 大安全隱患之一。

關於CSRF,要從一個故事開始~

老王丟錢事件

這個故事要從程式設計師老王丟了1萬塊錢說起,總之是進了小偷,找回無果。丟錢後的老王一直在思考,錢是怎麼丟的、為何丟錢、為何是我丟錢~~

後來老王出現了嚴重的心理問題,他決定報復社會。

老王首先研究了網路銀行系統,他發現轉帳是透過GET形式

https://bank.abc.com/withdraw?account=liuxiaoer&amount=1000&to=abei

這意思是說將liuxiaoer 的1000元錢轉給abei ,當然當請求到達銀行伺服器後,程式會驗證該請求是否來自合法的session並且該session的使用者就是liuxiaoer 並且已經登入。

老王自己也有一個銀行帳號wang2,他嘗試登入並且透過瀏覽器發送請求給銀行,代碼如下

https://bank.abc.com/withdraw?account=liuxiaoer&amount=1000&to=wang2

失敗了~因為目前登入帳號是老王自己,發送請求後伺服器發現session所屬用戶wang2和account=liuxiaoer並不是一個人,因此被拒絕。

也就是說這個操作必須是liuxiaoer 自己才可以,復仇的力量是可怕的,老王透過facebook層層找到了liuxiaoer 就是快遞員老劉的銀行帳號。

於是一個偉大的計畫誕生了,老王的計畫是這樣的。

1、先做一個網頁,在網頁中加入如下程式碼

src="https://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的情況下不能貿然的決絕服務,有可能這是一個合法請求。

添加Token

CSRF攻击之所以能成功,是因为黑客完全伪造了一次用户的正常请求(这也是浏览器无法拦截的原因),并且cookie信息就是用户自己的,那么我们如果在请求中放入一些黑客无法去伪造的信息(不存在与cookie中),不就可以抵御了么!

比如在请求前生成一个token放到session中,当请求发生时,将token从session拿出来和请求提交过来的token进行对比,如果相等则认证通过,否则拒绝。token时刻在变化,黑客无法去伪造。

针对于不同类型的请求一般方案是

  • GET 放到url中,比如http://url?csrftoken=xxxx

  • POST 放到表单的隐藏域

对于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.php
public 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攻擊的防範措施

以上是yii2的csrf策略部署,当然我还是推荐你使用 xdebug等调试工具 一步一步看看这个过程。

最后我在把上图的关键函数进行说明

  • generateCsrfToken() 该函数生成token并存到cookie或session中,该值不会随页面刷新而变化,它更多充当钥匙的作用,根绝它生成具体的csrfToken。

  • getCsrfToken() 生成具体的csrfToken,就是你在表单隐藏域中看到的那个值,这个值将来会传到服务器和真实的csrfToken进行对比,验证是否合法。

  • validateCsrfToken()  进行合法性验证,该函数得到一个真实的csrfToken然后和客户端上传来的csrfToken进行对比。

以上就是本文的全部内容,希望对大家的学习有所帮助,更多相关内容请关注PHP中文网!

相关推荐:

如何在yii2-wx中使用try_catch

关于Yii2中GridView的用法总结

以上是yii2對csrf攻擊的防範措施的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
PHP中的PDO是什麼?PHP中的PDO是什麼?Apr 28, 2025 pm 04:51 PM

本文討論了PHP數據對象(PDO),這是PHP中數據庫訪問的擴展名。它通過準備好的語句及其對MySQLI的好處,包括數據庫抽象和更好的錯誤處理,強調了PDO在增強安全性方面的作用。

php中的memcache是​​什麼?是否可以在幾個PHP項目之間共享一個memcache的一個實例?php中的memcache是​​什麼?是否可以在幾個PHP項目之間共享一個memcache的一個實例?Apr 28, 2025 pm 04:47 PM

memcache和memcached是通過減少數據庫負載加快Web應用程序的PHP緩存系統。可以在仔細的密鑰管理的項目之間共享一個實例。

使用MySQL和PHP創建新數據庫的步驟是什麼?使用MySQL和PHP創建新數據庫的步驟是什麼?Apr 28, 2025 pm 04:44 PM

文章討論了使用PHP創建和管理MySQL數據庫的步驟,專注於連接,創建,常見錯誤和安全措施。

JavaScript是否與PHP相互作用?JavaScript是否與PHP相互作用?Apr 28, 2025 pm 04:43 PM

本文討論了JavaScript和PHP如何通過HTTP請求間接相互作用,因為它們的環境不同。它涵蓋了將數據從JavaScript發送到PHP的方法

PHP中的梨是什麼?PHP中的梨是什麼?Apr 28, 2025 pm 04:38 PM

梨是可重複使用組件的PHP框架,通過包裝管理,編碼標準和社區支持增強開發。

PHP的用途是什麼?PHP的用途是什麼?Apr 28, 2025 pm 04:37 PM

PHP是一種多功能的腳本語言,主要用於Web開發,創建動態頁面,還可以用於命令行腳本,桌面應用程序和API開發。

PHP的舊名稱是什麼?PHP的舊名稱是什麼?Apr 28, 2025 pm 04:36 PM

文章討論了PHP從1995年的“個人主頁工具”到1998年的“ PHP:超文本預處理器”的演變,這反映了其超越個人網站的擴展使用。

如何防止會話固定攻擊?如何防止會話固定攻擊?Apr 28, 2025 am 12:25 AM

防止會話固定攻擊的有效方法包括:1.在用戶登錄後重新生成會話ID;2.使用安全的會話ID生成算法;3.實施會話超時機制;4.使用HTTPS加密會話數據,這些措施能確保應用在面對會話固定攻擊時堅不可摧。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

EditPlus 中文破解版

EditPlus 中文破解版

體積小,語法高亮,不支援程式碼提示功能

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。

mPDF

mPDF

mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),

DVWA

DVWA

Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中