记一次Session引起的数据操作漏洞
php的session id生成方法大致如下:
PHPSESSIONID = hash_func(客户端IP + 当前时间(秒)+ 当前时间(微妙)+ PHP自带的随机数生产器)
客户端访问服务器时会自动分配一个session id给客户端(用cookie存储),所以不同浏览器访问都能获得一个不同的session id
问题场景如下:
小V在做的一个项目上有代理提现功能,有天发现客户提现异常了!查看了一下最近的提现日志发现最近两次提现有问题。
代理用户在 11:48 时拥有余额2440余,之后发起提现20000元,余额剩余440,如此都是正常的。
但12点左右竟然又有一笔提现申请17000元,这情况让我慌了神,毕竟如果不靠金额变动日志查看异常就通过提现申请的话损失就大了。
问题暴露出来后小V急忙翻看了nginx日志、tp日志和binlog日志,结果得出金额变动都正常,且提现17000的时候执行也无异常??这
是什么情况,小V是做了提现判断的,如果当前金额低于提现金额是不予提现的,怎么会有这样的情况出现呢?
后来我怀疑是事务操作引起的,直接把金额更新了,今天有个代理客户反映代理后台余额显示为0,但是商户后台显示是300多,还说换了个浏览器就好了,这引起了我的注意,联想到异常提现的情况马上想到了会不会是Session问题。
看了眼代码,代理后台有个$this->user的对象属性,存的是当前登录用户的数据模型($this->user=session('agent.user')),这样每次调用$this->user其实调用的都是session里的值,这样的设计会导致数据库与session的值不对等!
猜想了漏洞来源后,来了一拨测试(用两个浏览器先进入代理后台),第一个浏览器申请提现20000,在看余额剩440了
第二个浏览器刷新看余额,呵!好家伙,钱没变动!
解决方案:
知道问题后就好办了,解决办法就是利用session里的用户id获取数据库里的用户信息就行了
$this->user=UserModel::get(session('agent.user')['id']);
发表评论: