fix(security): wallet balance check with FOR UPDATE, remove user-supplied ID in signup, hardcoded IP to env
This commit is contained in:
@@ -11,7 +11,6 @@ $password = filterRequest("password");
|
||||
$gender = filterRequest("gender");
|
||||
$birthdate = filterRequest("birthdate");
|
||||
$site = filterRequest("site");
|
||||
$id = filterRequest("id");
|
||||
|
||||
// تشفير البيانات الحساسة
|
||||
$phone = $encryptionHelper->encryptData($phone);
|
||||
@@ -39,14 +38,13 @@ try {
|
||||
exit;
|
||||
}
|
||||
|
||||
// إدخال البيانات الجديدة
|
||||
// إدخال البيانات الجديدة (مع ID تلقائي)
|
||||
$sql = "INSERT INTO passengers (
|
||||
id, phone, email, password, gender, birthdate, site, first_name, last_name
|
||||
) VALUES (
|
||||
:id, :phone, :email, :password, :gender, :birthdate, :site, :first_name, :last_name
|
||||
UUID_SHORT(), :phone, :email, :password, :gender, :birthdate, :site, :first_name, :last_name
|
||||
)";
|
||||
$stmt = $con->prepare($sql);
|
||||
$stmt->bindParam(":id", $id);
|
||||
$stmt->bindParam(":phone", $phone);
|
||||
$stmt->bindParam(":email", $email);
|
||||
$stmt->bindParam(":password", $hashedPassword);
|
||||
|
||||
@@ -44,8 +44,7 @@ function isAllowedSocketUrl(string $url): bool {
|
||||
}
|
||||
|
||||
function sendToLocationServer($action, $data) {
|
||||
// رابط سيرفر اللوكيشن الداخلي أو العام
|
||||
$url = "http://188.68.36.205:2021";
|
||||
$url = getenv('LOCATION_SERVER_URL') ?: 'http://188.68.36.205:2021';
|
||||
if (!isAllowedSocketUrl($url)) {
|
||||
error_log("[SSRF_BLOCKED] Attempted connection to: $url");
|
||||
return;
|
||||
|
||||
@@ -41,13 +41,12 @@ $passengerId = filterRequest("passengerId");
|
||||
$paymentAmount = filterRequest("paymentAmount");
|
||||
$paymentMethod = filterRequest("paymentMethod");
|
||||
$walletChecked = filterRequest("walletChecked"); // 'true' or 'false'
|
||||
$passengerWalletBurc = filterRequest("passengerWalletBurc"); // passenger balance before operation
|
||||
$authToken = filterRequest("authToken"); // kept for logging/audit, not used for auth
|
||||
|
||||
// --- Validate required fields ---
|
||||
if (empty($rideId) || empty($driverId) || empty($passengerId) ||
|
||||
!isset($paymentAmount) || empty($paymentMethod) ||
|
||||
!isset($walletChecked) || !isset($passengerWalletBurc)) {
|
||||
!isset($walletChecked)) {
|
||||
printFailure("Missing required parameters for payment processing.");
|
||||
exit;
|
||||
}
|
||||
@@ -79,33 +78,59 @@ try {
|
||||
|
||||
// 3b. Deduct from passenger wallet (if wallet payment)
|
||||
if ($walletChecked === 'true') {
|
||||
// Check actual balance with row lock
|
||||
$stmtBalance = $con->prepare(
|
||||
"SELECT COALESCE(SUM(balance), 0) AS current_balance
|
||||
FROM passengerWallet
|
||||
WHERE passenger_id = :passenger_id
|
||||
FOR UPDATE"
|
||||
);
|
||||
$stmtBalance->execute([':passenger_id' => $passengerId]);
|
||||
$balanceRow = $stmtBalance->fetch(PDO::FETCH_ASSOC);
|
||||
$currentBalance = floatval($balanceRow['current_balance']);
|
||||
|
||||
$deductionAmount = floatval($paymentAmount);
|
||||
if ($currentBalance < $deductionAmount) {
|
||||
throw new Exception("Insufficient wallet balance. Required: $deductionAmount, Available: $currentBalance");
|
||||
}
|
||||
|
||||
$stmtPassengerWallet = $con->prepare(
|
||||
"INSERT INTO `passengerWallet` (`passenger_id`, `balance`)
|
||||
VALUES (:passenger_id, :balance)"
|
||||
);
|
||||
$stmtPassengerWallet->execute([
|
||||
':passenger_id' => $passengerId,
|
||||
':balance' => (-1) * floatval($paymentAmount),
|
||||
':balance' => (-1) * $deductionAmount,
|
||||
]);
|
||||
|
||||
if ($stmtPassengerWallet->rowCount() <= 0) {
|
||||
throw new Exception("Failed to deduct from passenger wallet.");
|
||||
}
|
||||
}
|
||||
|
||||
// 3c. Settle existing passenger debt (if balance was negative)
|
||||
if (floatval($passengerWalletBurc) < 0) {
|
||||
$stmtPassengerDebt = $con->prepare(
|
||||
"INSERT INTO `passengerWallet` (`passenger_id`, `balance`)
|
||||
VALUES (:passenger_id, :balance)"
|
||||
// 3c. Settle existing debt (use actual balance after deduction)
|
||||
$stmtBalanceAfter = $con->prepare(
|
||||
"SELECT COALESCE(SUM(balance), 0) AS balance_after
|
||||
FROM passengerWallet
|
||||
WHERE passenger_id = :passenger_id
|
||||
FOR UPDATE"
|
||||
);
|
||||
$stmtPassengerDebt->execute([
|
||||
':passenger_id' => $passengerId,
|
||||
':balance' => (-1) * floatval($passengerWalletBurc),
|
||||
]);
|
||||
$stmtBalanceAfter->execute([':passenger_id' => $passengerId]);
|
||||
$balanceAfterRow = $stmtBalanceAfter->fetch(PDO::FETCH_ASSOC);
|
||||
$balanceAfter = floatval($balanceAfterRow['balance_after']);
|
||||
|
||||
if ($stmtPassengerDebt->rowCount() <= 0) {
|
||||
throw new Exception("Failed to settle passenger debt.");
|
||||
if ($balanceAfter < 0) {
|
||||
$stmtPassengerDebt = $con->prepare(
|
||||
"INSERT INTO `passengerWallet` (`passenger_id`, `balance`)
|
||||
VALUES (:passenger_id, :balance)"
|
||||
);
|
||||
$stmtPassengerDebt->execute([
|
||||
':passenger_id' => $passengerId,
|
||||
':balance' => (-1) * $balanceAfter,
|
||||
]);
|
||||
|
||||
if ($stmtPassengerDebt->rowCount() <= 0) {
|
||||
throw new Exception("Failed to settle passenger debt.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user