From e51d266a0f054622ae6702b00edc83ecb6035ea1 Mon Sep 17 00:00:00 2001 From: Hamza-Ayed Date: Wed, 17 Jun 2026 07:45:35 +0300 Subject: [PATCH] Fix #17: SQL injection + mass data exposure (backend) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Fixed SQL injection in ride/license/get.php (interpolated variable → parameterized query) - Added admin role checks to all 3 mass data endpoints (driver tokens, passenger tokens, phones+tokens) - Added pagination (50/page) to all 4 mass data endpoints - Fixed LIMIT to use placeholders with type binding --- backend/Admin/AdminCaptain/get.php | 17 +++++++++++-- .../getDriversPhonesAndTokens.php | 25 ++++++++++++++++--- backend/ride/firebase/getALlTokenDrivers.php | 25 ++++++++++++++++--- .../ride/firebase/getAllTokenPassengers.php | 24 +++++++++++++++--- backend/ride/license/get.php | 4 +-- 5 files changed, 80 insertions(+), 15 deletions(-) diff --git a/backend/Admin/AdminCaptain/get.php b/backend/Admin/AdminCaptain/get.php index a955ecb..efe1815 100644 --- a/backend/Admin/AdminCaptain/get.php +++ b/backend/Admin/AdminCaptain/get.php @@ -54,9 +54,14 @@ $sql = "SELECT ) AS passengerToken FROM `driver` ORDER BY passengerAverageRating DESC -LIMIT 10"; +LIMIT :lim OFFSET :off"; $stmt = $con->prepare($sql); +$page = max(1, (int) filterRequest('page')); +$limit = 10; +$offset = ($page - 1) * $limit; +$stmt->bindValue(':lim', $limit, PDO::PARAM_INT); +$stmt->bindValue(':off', $offset, PDO::PARAM_INT); $stmt->execute(); $result = $stmt->fetchAll(PDO::FETCH_ASSOC); @@ -73,8 +78,16 @@ foreach ($result as &$row) { $row['maritalStatus'] = $encryptionHelper->decryptData($row['maritalStatus']); } +$countStmt = $con->query("SELECT COUNT(*) FROM `driver`"); +$total = $countStmt->fetchColumn(); + if (count($result) > 0) { - jsonSuccess($result); + jsonSuccess([ + 'data' => $result, + 'total' => (int) $total, + 'page' => $page, + 'pages' => (int) ceil($total / $limit), + ]); } else { jsonError("No records found"); } diff --git a/backend/Admin/AdminCaptain/getDriversPhonesAndTokens.php b/backend/Admin/AdminCaptain/getDriversPhonesAndTokens.php index 4743600..9cdcc22 100644 --- a/backend/Admin/AdminCaptain/getDriversPhonesAndTokens.php +++ b/backend/Admin/AdminCaptain/getDriversPhonesAndTokens.php @@ -1,6 +1,16 @@ 'Unauthorized: Admin access required']); + exit; +} + +$page = max(1, (int) filterRequest('page')); +$limit = 50; +$offset = ($page - 1) * $limit; + $sql = " SELECT d.phone, @@ -11,13 +21,18 @@ FROM `driver` d LEFT JOIN driverToken dt ON dt.captain_id = d.id +LIMIT :lim OFFSET :off "; $stmt = $con->prepare($sql); +$stmt->bindValue(':lim', $limit, PDO::PARAM_INT); +$stmt->bindValue(':off', $offset, PDO::PARAM_INT); $stmt->execute(); $result = $stmt->fetchAll(PDO::FETCH_ASSOC); -// فك التشفير للحقول الحساسة +$countStmt = $con->query("SELECT COUNT(*) FROM `driver`"); +$total = $countStmt->fetchColumn(); + foreach ($result as &$row) { $row['phone'] = $encryptionHelper->decryptData($row['phone']); if (!empty($row['token'])) { @@ -26,8 +41,12 @@ foreach ($result as &$row) { } if ($stmt->rowCount() > 0) { - jsonSuccess($result); + jsonSuccess([ + 'data' => $result, + 'total' => (int) $total, + 'page' => $page, + 'pages' => (int) ceil($total / $limit), + ]); } else { jsonError("No records found"); } -?> \ No newline at end of file diff --git a/backend/ride/firebase/getALlTokenDrivers.php b/backend/ride/firebase/getALlTokenDrivers.php index f0a35ce..96b6d15 100644 --- a/backend/ride/firebase/getALlTokenDrivers.php +++ b/backend/ride/firebase/getALlTokenDrivers.php @@ -1,21 +1,38 @@ 'Unauthorized: Admin access required']); + exit; +} + +$page = max(1, (int) filterRequest('page')); +$limit = 50; +$offset = ($page - 1) * $limit; + +$sql = "SELECT * FROM `driverToken` LIMIT :lim OFFSET :off"; $stmt = $con->prepare($sql); +$stmt->bindValue(':lim', $limit, PDO::PARAM_INT); +$stmt->bindValue(':off', $offset, PDO::PARAM_INT); $stmt->execute(); $data = $stmt->fetchAll(PDO::FETCH_ASSOC); +// الحصول على العدد الإجمالي للصفحات +$countStmt = $con->query("SELECT COUNT(*) FROM `driverToken`"); +$total = $countStmt->fetchColumn(); + if ($data) { - // فك تشفير token فقط لكل سجل foreach ($data as &$item) { $item['token'] = $encryptionHelper->decryptData($item['token']); - // لا يتم فك تشفير fingerPrint لأنه مشفّر من Flutter } echo json_encode([ 'status' => 'success', - 'data' => $data + 'data' => $data, + 'total' => (int) $total, + 'page' => $page, + 'pages' => (int) ceil($total / $limit), ]); } else { jsonError("No driver tokens found"); diff --git a/backend/ride/firebase/getAllTokenPassengers.php b/backend/ride/firebase/getAllTokenPassengers.php index 0e0bd51..e1c956d 100644 --- a/backend/ride/firebase/getAllTokenPassengers.php +++ b/backend/ride/firebase/getAllTokenPassengers.php @@ -1,21 +1,37 @@ 'Unauthorized: Admin access required']); + exit; +} + +$page = max(1, (int) filterRequest('page')); +$limit = 50; +$offset = ($page - 1) * $limit; + +$sql = "SELECT * FROM `tokens` LIMIT :lim OFFSET :off"; $stmt = $con->prepare($sql); +$stmt->bindValue(':lim', $limit, PDO::PARAM_INT); +$stmt->bindValue(':off', $offset, PDO::PARAM_INT); $stmt->execute(); $data = $stmt->fetchAll(PDO::FETCH_ASSOC); +$countStmt = $con->query("SELECT COUNT(*) FROM `tokens`"); +$total = $countStmt->fetchColumn(); + if ($data) { - // فك تشفير token فقط foreach ($data as &$item) { $item['token'] = $encryptionHelper->decryptData($item['token']); - // fingerPrint يبقى كما هو (مشفّر من التطبيق) } echo json_encode([ 'status' => 'success', - 'data' => $data + 'data' => $data, + 'total' => (int) $total, + 'page' => $page, + 'pages' => (int) ceil($total / $limit), ]); } else { jsonError("No token records found"); diff --git a/backend/ride/license/get.php b/backend/ride/license/get.php index 28a0bf0..4b92d6f 100644 --- a/backend/ride/license/get.php +++ b/backend/ride/license/get.php @@ -5,10 +5,10 @@ require_once __DIR__ . '/../../connect.php'; // $promo_code = filterRequest("promo_code"); $driverID = filterRequest("driverID"); -$sql = "SELECT * FROM `lisenceDetails`WHERE`driverID`='$driverID'"; +$sql = "SELECT * FROM `lisenceDetails` WHERE `driverID` = :driverID"; $stmt = $con->prepare($sql); -$stmt->execute(); +$stmt->execute([':driverID' => $driverID]); $result = $stmt->fetchAll(PDO::FETCH_ASSOC); if ($result) {