【发布时间】:2015-08-16 23:56:30
【问题描述】:
假设我使用 CodeIgniter/PHP 和 MySQL 创建了一个在线银行系统,并且有以下内容可以从我的银行账户中提取资金:
function withdraw($user_id, $amount) {
$amount = (int)$amount;
// make sure we have enough in the bank account
$balance = $this->db->where('user_id', $user_id)
->get('bank_account')->balance;
if ($balance < $amount) {
return false;
}
// take the money out of the bank
$this->db->where('user_id', $user_id)
->set('balance', 'balance-'.$amount, false)
->update('bank_account');
// put the money in the wallet
$this->db->where('user_id', $user_id)
->set('balance', 'balance+'.$amount, false)
->update('wallet');
return true;
}
首先,我们检查用户是否可以执行提款,然后我们从账户中减去,然后我们添加到钱包中。
问题是我几乎可以同时发送多个请求(这对于使用curl 来说基本上是微不足道的)。每个请求都有自己的线程,所有线程都同时运行。因此,每个人都会检查我的银行是否有足够的钱(我会这样做),然后每个人都会进行取款。结果,如果我开始余额为 100,并且我同时发送两个 curl 请求导致提取 100,那么我的钱包中最终有 200 和银行帐户中的 -100,这应该是不可能的。
解决此类TOCTOU漏洞的正确“CodeIgniter”方法是什么?
【问题讨论】:
标签: php mysql codeigniter session