项目中遇到的水平越权漏洞及修复方法

来源:互联网 发布:电影资源知乎 编辑:程序博客网 时间:2024/05/16 10:55

项目基于thinkphp5框架,虽然说框架底层为开发者提供了基本的参数过滤和参数绑定等安全防护。能在很大程度上防范XSS攻击和SQL注入,但在在开发中也应该注意避免产生业务逻辑漏洞和做好用户权限认证。今天在项目中发现了一个安全漏洞:A用户可以修改甚至删除B用户的收货地址。这个漏洞出现的原因是开发者没有对请求进行严格的权限认证,本文主要叙述发现漏洞的过程及修复的方法。

一. 此段代码的逻辑是当收到get请求返回对应addrIdpostaddrId修改收货地址。该行代码漏洞其一是没有对用户的输入进行验证便直接通过$_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. 日常开发中要多留意业务逻辑可能出现的漏洞和水平权限漏洞或者其它我未发现的漏洞,不能因为框架本身提供了基本的安全防护就对安全掉以轻心,毕竟咱要立志往服务器端发展,加油。

原创粉丝点击