Что может быть проблемой безопасности в этом Perl? - PullRequest
0 голосов
/ 31 января 2019
$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 голосов
/ 31 января 2019

Задача 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

Откуда взялись средства назад?В большинстве сценариев есть вероятность, что что-то сделать со снятыми средствами не удастся.Если это так, то вместо того, чтобы снимать средства, вам, вероятно, следует их зарезервировать (пометить их как недоступные) и снимать средства только после того, как они фактически были использованы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...