此Perl中可能有什么安全问题?

时间:2019-01-31 13:34:46

标签: perl security

$transfer_amount = GetTransferAmount();
$balance = GetBalanceFromDatabase();

if ($transfer_amount < 0) {
    FatalError("Bad Transfer Amount");
}

$newbalance = $balance - $transfer_amount;
if (($balance - $transfer_amount) < 0) {
    FatalError("Insufficient Funds");
}

SendNewBalanceToDatabase($newbalance);
NotifyUser("Transfer of $transfer_amount succeeded.");
NotifyUser("New balance: $newbalance");

如果有一个安全问题,此代码可能有人解释一下吗?

1 个答案:

答案 0 :(得分:6)

问题1

财务交易中非常重要的安全机制是执行审计的能力。没有迹象表明该代码会留下任何形式的纸张痕迹。一个人不仅应该更新余额,而且还要创建交易记录。

问题2

该代码存在竞争条件。考虑如果两个动作同时发生,会发生什么。

Process 1                                         Process 2
===============================================   ===============================================
$xfer_amt = GetTransferAmount();
$balance = GetBalanceFromDatabase();

if ($xfer_amt < 0) {
    FatalError("Bad Transfer Amount");
}

                                                  $xfer_amt = GetTransferAmount();                      
                                                  $balance = GetBalanceFromDatabase();

                                                  if ($xfer_amt < 0) {
                                                      FatalError("Bad Transfer Amount");
                                                  }

                                                  $newbalance = $balance - $xfer_amt;
                                                  if (($balance - $xfer_amt) < 0) {
                                                      FatalError("Insufficient Funds");
                                                  }

$newbalance = $balance - $xfer_amt;
if (($balance - $xfer_amt) < 0) {
    FatalError("Insufficient Funds");
}

SendNewBalanceToDatabase($newbalance);
NotifyUser("Transfer of $xfer_amt succeeded.");
NotifyUser("New balance: $newbalance");

                                                  SendNewBalanceToDatabase($newbalance);
                                                  NotifyUser("Transfer of $xfer_amt succeeded.");
                                                  NotifyUser("New balance: $newbalance");

(重命名了一个变量,使代码在屏幕上更合适。)

数据库只会最终被其中一项交易扣除。

在合并第一个问题的解决方案时,正确执行此操作会变得更加复杂,因为您需要确保余额始终与事务记录保持同步(考虑并发事务,网络故障,断电,等)。

问题3

资金从何而来?在大多数情况下,使用提取的资金做某事可能会失败。如果是这样,您可能不应该提取资金,而应该保留它们(标记为不可用),并且只有在实际使用它们之后才提取它们。