PHP開發中csrf攻擊的示範與防範詳解
CSRF的全名為Cross-site request forgery,它的中文名為跨站請求偽造(偽造跨站請求【這樣讀順口一點】)CSRF是一種夾持用戶在已經登陸的web應用程式上執行非本意的操作的攻擊方式。相較於XSS,CSRF是利用了系統對頁面瀏覽器的信任,XSS則利用了系統對使用者的信任。
csrf攻擊,即cross site request forgery跨站(域名)請求偽造,這裡的forgery就是偽造的意思。網路上有很多關於csrf的介紹,例如一位前輩的文章CSRF的攻擊方式詳解,參考這篇文章簡單解釋下:csrf 攻擊能夠實現依賴於這樣一個簡單的事實:我們在用瀏覽器瀏覽網頁時通常會開啟好幾個瀏覽器標籤(或視窗),如果我們登入了一個網站A,網站A如果是透過cookie來追蹤使用者的會話,那麼在使用者登入了網站A之後,網站A就會在使用者的客戶端設置cookie,假如網站A有一個頁面siteA-page.php(url資源)被網站B知道了url位址,而這個頁面的位址以某種方式被嵌入到了B網站的一個頁面siteB-page.php中,如果這時使用者在維持A網站會話的同時開啟了B網站的siteB-page.php,那麼只要siteB-page.php頁面可以觸發這個url位址(請求A網站的url資源)就實現了csrf攻擊。
上面的解釋很拗口,下面舉個簡單的例子來示範下。
1,背景和正常的請求流程
A網站網域為html5.yang.com,它有一個/get-update.php?uid=uid&username=username位址,可以看到這個位址可以透過get方法傳遞一些參數,假如這個頁面的邏輯是:它透過判斷uid是否合法來更新username,這個頁面腳本如下:
# #
<?php // 这里简便起见, 从data.json中取出数据代替请求数据库 $str = file_get_contents('data.json'); $data = json_decode($str, true); // 检查cookie和请求更改的uid, 实际应检查数据库中的用户是否存在 empty($_COOKIE['uid']) ||empty($_GET['uid']) || $_GET['uid'] != $data['id'] ? die('非法用户') : ''; // 检查username参数 $data['username'] = empty($_GET['username']) ? die('用户名不能为空') : $_GET['username']; // 更新数据 $data['username'] = $_GET['username']; if(file_put_contents('data.json', json_encode($data))) { echo "用户名已更改为{$data['username']}<br>"; } else { die('更新失败'); }
<?php // 这里用一个data.json文件保存用户数据,模拟数据库中的数据 // 先初始化data.json中的数据为{"id":101,"username":"jack"}, 注意这句只让它执行一次, 然后把它注释掉 // file_put_contents('data.json','{"id":101,"username":"jack"}'); $data = json_decode(file_get_contents('data.json'), true); // 这里为了简便, 省略了用户身份验证的过程 if ($data['username']) { // 设置cookie setcookie('uid', $data['id'], 0); echo "登录成功, {$data['username']}<br>"; } ?> <a href="http://html5.yang.com/csrfdemo/get-update.php?uid=101&username=json" rel="external nofollow" > 更新用户名为json </a>
# #用點擊頁面中的連結來到get-update.php頁面:
#上面是正常的請求流程,下面來看B站點是如何實作csrf攻擊的。
2,csrf攻擊的最簡單實作
B網站網域為test.yang.com,它有一個頁面csrf.php,只要用戶在維持A網站會話的同時打開了這個頁面,那麼B站點就可以實現csrf攻擊。至於為什麼會打開......,其實這種情景在我們瀏覽網頁時是很常見的,比如我在寫這篇博客時,寫著寫著感覺對csrf某個地方不懂,然後就百度了,結果百度出來好多結果,假如說有個網站叫csrf百科知識,這個網站對csrf介紹的非常詳細、非常權威,那麼我很可能會點進去看,但是這個網站其實是個釣魚網站,它在某在瀏覽頻率很高的頁面中嵌入了我部落格編輯頁面的url位址,那麼它就可以實現對我部落格的csrf攻擊。好了,言歸正傳,下面來看下csrf.php腳本程式碼:
<?php ?> <img src="http://html5.yang.com/csrfdemo/get-update.php?uid=101&username=jsonp">
可以看到上面的程式碼沒有php程式碼,只有一個img標籤,img標籤的src就是A站點的那個更新用戶名的鏈接,只不過把username改為了jsonp,訪問站點B的csrf.php這個頁面:
下面再來訪問下A網站的csrfdemo.php頁面:
可以看到使用者名稱被修改為了jsonp。
簡單分析下:B網站的這個csrf.php利用了html中的img標籤,我們都知道img標籤有個src屬性,屬性值指向需要載入的圖片位址,當頁面載入時,載入圖片就相當於向src指向的位址發動http請求,只要把圖片的位址修改為某個腳本位址,這樣自然就實現了最簡單的csrf攻擊。如此說來,其實csrf很容易實現,只不過大家都是“正人君子”,誰沒事會閒著去做這種“下三濫”的事情。但是害人之心不可有,防人之心不可無。下面看如何簡單防範這種最簡單的csrf攻擊。
3,簡單防範措施
其實防範措施也比較簡單,A網站可以在get-update.php腳本中判斷請求頭的來源,如果來源不是A網站就可以截斷請求,以下在get-update.php增加些程式碼:
<?php // 检查上一页面是否为当前站点下的页面 if (!empty($_SERVER['HTTP_REFERER'])) { if (parse_url($_SERVER['HTTP_REFERER'], PHP_URL_HOST) != 'html5.yang.com') { // 可以设置http错误码或者指向一个无害的url地址 //header('HTTP/1.1 404 not found'); //header('HTTP/1.1 403 forbiden'); header('Location: http://html5.yang.com/favicon.ico'); // 这里需要注意一定要exit(), 否则脚本会接着执行 exit(); } } $str = file_get_contents('data.json'); // 代码省略
但是,这样就万事大吉了吗,如果http请求头被伪造了呢?A站点升级了防御,B站点同时也可以升级攻击,通过curl请求来实现csrf,修改B站点的csrf.php代码如下:
<?php $url = 'http://html5.yang.com/csrfdemo/get-update.php?uid=101&username=jsonp'; $refer = 'http://html5.yang.com/'; // curl方法发起csrf攻击 $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); // 设置Referer curl_setopt($ch, CURLOPT_REFERER, $refer); // 这里需要携带上cookie, 因为A站点get-update.php对cooke进行了判断 curl_setopt($ch, CURLOPT_COOKIE, 'uid=101'); curl_exec($ch); curl_close($ch); ?> <img src="http://html5.yang.com/csrfdemo/get-update.php?uid=101&username=jsonp">
这样同样可以实现csrf攻击的目的。那么就没有比较好的防范方法了吗?
4,小结
下面我们回到问题的开始,站点A通过cookie来跟踪用户会话,在cookie中存放了重要的用户信息uid,get-update.php脚本通过判断用户的cookie正确与否来决定是否更改用户信息,看来靠cookie来跟踪会话并控制业务逻辑是不太安全的,还有最严重的一点:get-update.php通过get请求来修改用户信息,这个是大忌。所以站点A可以接着升级防御:用session来代替cookie来跟踪用户会话信息,将修改用户信息的逻辑重写,只允许用post方法来请求用户信息。站点B同样可以升级攻击:curl可以构造post请求,劫持session等等,不过这些我还没研究过,后续再说吧。
相关推荐:
php curl带有csrf-token验证模拟提交实例详解
以上是PHP開發中csrf攻擊的示範與防範詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

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

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

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

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

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

JWT是一種基於JSON的開放標準,用於在各方之間安全地傳輸信息,主要用於身份驗證和信息交換。 1.JWT由Header、Payload和Signature三部分組成。 2.JWT的工作原理包括生成JWT、驗證JWT和解析Payload三個步驟。 3.在PHP中使用JWT進行身份驗證時,可以生成和驗證JWT,並在高級用法中包含用戶角色和權限信息。 4.常見錯誤包括簽名驗證失敗、令牌過期和Payload過大,調試技巧包括使用調試工具和日誌記錄。 5.性能優化和最佳實踐包括使用合適的簽名算法、合理設置有效期、

字符串是由字符組成的序列,包括字母、數字和符號。本教程將學習如何使用不同的方法在PHP中計算給定字符串中元音的數量。英語中的元音是a、e、i、o、u,它們可以是大寫或小寫。 什麼是元音? 元音是代表特定語音的字母字符。英語中共有五個元音,包括大寫和小寫: a, e, i, o, u 示例 1 輸入:字符串 = "Tutorialspoint" 輸出:6 解釋 字符串 "Tutorialspoint" 中的元音是 u、o、i、a、o、i。總共有 6 個元

PHP的魔法方法有哪些? PHP的魔法方法包括:1.\_\_construct,用於初始化對象;2.\_\_destruct,用於清理資源;3.\_\_call,處理不存在的方法調用;4.\_\_get,實現動態屬性訪問;5.\_\_set,實現動態屬性設置。這些方法在特定情況下自動調用,提升代碼的靈活性和效率。

靜態綁定(static::)在PHP中實現晚期靜態綁定(LSB),允許在靜態上下文中引用調用類而非定義類。 1)解析過程在運行時進行,2)在繼承關係中向上查找調用類,3)可能帶來性能開銷。

PHP和Python各有優勢,選擇依據項目需求。 1.PHP適合web開發,尤其快速開發和維護網站。 2.Python適用於數據科學、機器學習和人工智能,語法簡潔,適合初學者。

PHP在電子商務、內容管理系統和API開發中廣泛應用。 1)電子商務:用於購物車功能和支付處理。 2)內容管理系統:用於動態內容生成和用戶管理。 3)API開發:用於RESTfulAPI開發和API安全性。通過性能優化和最佳實踐,PHP應用的效率和可維護性得以提升。

PHP是一種廣泛應用於服務器端的腳本語言,特別適合web開發。 1.PHP可以嵌入HTML,處理HTTP請求和響應,支持多種數據庫。 2.PHP用於生成動態網頁內容,處理表單數據,訪問數據庫等,具有強大的社區支持和開源資源。 3.PHP是解釋型語言,執行過程包括詞法分析、語法分析、編譯和執行。 4.PHP可以與MySQL結合用於用戶註冊系統等高級應用。 5.調試PHP時,可使用error_reporting()和var_dump()等函數。 6.優化PHP代碼可通過緩存機制、優化數據庫查詢和使用內置函數。 7

PHP仍然具有活力,其在現代編程領域中依然佔據重要地位。 1)PHP的簡單易學和強大社區支持使其在Web開發中廣泛應用;2)其靈活性和穩定性使其在處理Web表單、數據庫操作和文件處理等方面表現出色;3)PHP不斷進化和優化,適用於初學者和經驗豐富的開發者。
