原文地址:https://blog.csdn.net/u013230444/article/details/73359704
項目基於thinkphp5框架,雖然說框架底層為開發者提供了基本的參數過濾和參數綁定等安全防護。能在很大程度上防范XSS攻擊和SQL注入,但在在開發中也應該注意避免產生業務邏輯漏洞和做好用戶權限認證。今天在項目中發現了一個安全漏洞:A用戶可以修改甚至刪除B用戶的收貨地址。這個漏洞出現的原因是開發者沒有對請求進行嚴格的權限認證,本文主要敘述發現漏洞的過程及修復的方法。
一. 此段代碼的邏輯是當收到get請求返回對應addrId的收貨地址,而收到post請求后則根據addrId的收貨地址,而收到post請求后則根據addrId修改收貨地址。該行代碼漏洞其一是沒有對用戶的輸入進行驗證便直接通過$_POST獲得用戶傳來的參數。其二是雖然在基類中調用了getUserInfo方法對用戶傳來的token進行驗證,但這只驗證了請求是否來自已注冊的用戶,而沒有驗證該用戶是否有權限更改收貨地址。所以黑客可以通過構造一個post請求就可修改任意用戶的收貨地址修復的辦法是只要將
public function getUserInfo($token) { if (!$token) { $this->api(404, null, 'require token'); } return Cache::get($token); }
public function address($addrId){
$address =Address::get($addrId);
if (request()->isGet()){
return $address;
}else if(request()->isPost()){
// 此為產生漏洞的代碼
$result =$address->allowField(true)->save($_POST);
if(input('post.ismain') ==1){
$userAddress = Address::where('yunsu_id',$this->getUserId($_SERVER['HTTP_TOKEN']))->where('address_id','neq',$addrId)->where('ismain',1)->select();
foreach($userAddress as $item){
$item->ismain = 0;
$item->save();
}
}
...
修復的辦法是只要將
$result =$address->allowField(true)->save($_POST);
修改為下面的代碼即可:
$data = $address->allowField(true)
->where('yunsu_id', $this>getUserId($_SERVER['HTTP_TOKEN']))
->where('address_id', $addrId)
->find();
$result = $data->isUpdate(true)->save(input('post.')
public function getUserId($token)
{
$data = json_decode(Cache::get($token));
return $data->user_id;
}
getUserId方法的作用是獲取用戶登陸時保存在緩存中的用戶id。修改后的代碼不僅通過tp5的助手函數input()對參數進行過濾,還對用戶id進行驗證,從而避免a用戶更改b用戶收貨地址的漏洞。
此外還有另外一個可以刪除其他用戶收貨地址的漏洞,漏洞代碼如下:
public function del() { $address = Address::get(input('post.addrId')); //如果刪除的是默認地址,那就把第一個作為默認地址IBA if ($address->ismain == 1) { $addrList = Address::where('yunsu_id', $this->getUserId($_SERVER['HTTP_TOKEN']))->select(); $addrList[0]->ismain = 1; $addrList[0]->save(); } $result = $address->delete(); if ($result) { $this->api(100, $address, '刪除成功'); } else { $this->api(101, $address, '刪除失敗'); } }
同上面修改的例子,黑客可以通過反編譯APP或者其他手段獲得請求url,然后通過注冊用戶獲得服務器端傳來的token,最后在header中添加token並發送post請求來刪除其他用戶的收貨地址(想想都蛋疼…)。具體修改的例子 跟上面修改的差不多也不再多敘述。
總結
1. 理論上來說因為服務器端使用的是http服務而不是https,實際上還是可以在用戶注冊時通過抓包工具獲取token來進行惡意操作,但加了權限認證之后黑客只能通過構造請求來對token對應的用戶進行惡意操作;
2. 日常開發中要多留意業務邏輯可能出現的漏洞和水平權限漏洞或者其它我未發現的漏洞,不能因為框架本身提供了基本的安全防護就對安全掉以輕心,畢竟咱要立志往服務器端發展,加油。
