fix(security): wallet balance check with FOR UPDATE, remove user-supplied ID in signup, hardcoded IP to env

This commit is contained in:
Hamza-Ayed
2026-06-17 06:53:00 +03:00
parent 3dad979eb5
commit 1d3ea597f4
3 changed files with 43 additions and 21 deletions

View File

@@ -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);

View File

@@ -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;

View File

@@ -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.");
}
}
}