# دليل الإصلاحات الشامل - مشروع سيرو **التاريخ:** 16 يونيو 2026 **المرحلة:** التطبيق العملي للإصلاحات **الحالة:** قيد التطوير --- ## النقطة 1️⃣: مشكلة البصمة الضعيفة (Weak Fingerprint Authentication) ### الملفات المتأثرة: - `backend/login.php` (الراكب) - `backend/loginJwtDriver.php` (السائق) ### المشكلة الحقيقية: ```php // ❌ الحالة الحالية في login.php $fpVerified = hash_equals($storedFp, $fingerprint); // ✅ يحمي من timing attacks فقط // ⚠️ لكن البصمة نفسها ضعيفة وقابلة للاستخراج ``` **لماذا ضعيفة؟** - البصمة مستخرجة من جهاز المستخدم (ANDROID_ID + IMEI + MAC + Build.MODEL) - يمكن استخراجها عبر: - Frida/Objection أثناء التطبيق - ADB إذا كان USB debugging مفعل - مفاتيح الجهاز المُخزنة - بمجرد استخراج البصمة، يمكن تزويرها بنسخ نفس القيمة ### الحل: تطبيق MFA (Multi-Factor Authentication) **المتطلبات:** ``` عامل 1: بصمة الجهاز (الحالي) ✅ عامل 2: OTP عبر SMS ← أضف هذا عامل 3: رمز الخادم (Server Token) ← أضف هذا ``` --- ## النقطة 2️⃣: مشكلة التشفير - IV الثابت ### الملف المتأثر: - `backend/encrypt_decrypt.php` (الأساسي) ### المشكلة الفعلية: ```php // ❌ المشكلة الحرجة جداً $iv = getenv('initializationVector'); // 16 بايت ثابت! public function encryptData($plainText) { $plainText = mb_convert_encoding($plainText, 'UTF-8'); $paddedText = $this->addPadding($plainText); $encrypted = openssl_encrypt($paddedText, 'AES-256-CBC', $this->key, OPENSSL_RAW_DATA, $this->iv); // ↑ نفس IV في كل مرة = نفس ciphertext لنفس plaintext! return base64_encode($encrypted); } ``` **مثال عملي:** ``` التشفير الأول: "+20123456789" → "abc123xyz==" التشفير الثاني: "+20123456789" → "abc123xyz==" (متطابق!) ⚠️ هجوم معروف - يمكن كسر التشفير تماماً ``` ### الحل: توليد IV عشوائي ```php ✅ الحل الصحيح: public function encryptData($plainText) { $plainText = mb_convert_encoding($plainText, 'UTF-8'); $paddedText = $this->addPadding($plainText); // توليد IV عشوائي لكل تشفير $randomIV = openssl_random_pseudo_bytes(16); $encrypted = openssl_encrypt($paddedText, 'AES-256-CBC', $this->key, OPENSSL_RAW_DATA, $randomIV); // ضمّ IV مع النص المشفر $result = $randomIV . $encrypted; return base64_encode($result); } public function decryptData($encryptedData) { $encrypted = base64_decode($encryptedData); // استخرج IV من أول 16 بايت $iv = substr($encrypted, 0, 16); $ciphertext = substr($encrypted, 16); $decrypted = openssl_decrypt($ciphertext, 'AES-256-CBC', $this->key, OPENSSL_RAW_DATA, $iv); return $this->removePadding($decrypted); } ``` **الخطوات:** 1. توليد 16 بايت عشوائية → `openssl_random_pseudo_bytes(16)` 2. تشفير البيانات بـ IV العشوائي 3. ضمّ IV + Ciphertext 4. تحويل إلى base64 5. عند فك التشفير: استخرج IV + Ciphertext وفك التشفير --- ## النقطة 3️⃣: SQL Injection - الحالة الحالية وضح! ### الملف المتأثر: - `backend/functions.php` (في `findBestDrivers()`) ### الحالة الحالية - ممتازة ✅ ```php // ✅ هذا الكود **آمن تماماً** من SQL Injection $carType = trim($carType); $allowedCarTypes = [ 'Comfort', 'Mishwar Vip', 'Scooter', 'Pink Bike', 'Electric', 'Lady', 'Van', 'Awfar Car', 'Fixed Price', 'Speed', 'Rayeh Gai' ]; // ✅ استخدام Allowlist (أفضل طريقة) if (!in_array($carType, $allowedCarTypes, true)) { $carType = 'Speed'; } // ✅ معاملات SQL آمنة $stmt = $con->prepare($sql); $stmt->execute($allParams); ``` ### لماذا هذا آمن؟ 1. **Allowlist:** قائمة بيضاء للقيم المسموحة فقط 2. **Prepared Statements:** معاملات آمنة 3. **Type Strict (`true`):** التحقق الدقيق (`in_array(..., true)`) ### المشاكل المتبقية: **نقاط أخرى قد تحتاج فحص:** - `/backend/auth/` - هل تستخدم prepared statements؟ - `/backend/ride/` - هل جميع الاستعلامات آمنة؟ - `/walletintaleq.intaleq.xyz/v2/main/` - **حرج! تحتاج فحص كامل** --- ## النقطة 4️⃣: نظام المحفظة - أهم نقطة 🔴 ### الملفات المتأثرة: ``` /walletintaleq.intaleq.xyz/v2/main/ride/driverWallet/ ├── add.php ..................... 🔴 حرج - بلا مصادقة ├── transfer.php ............... ⚠️ عالي ├── update.php ................. ⚠️ عالي ├── addFromAdmin.php ........... 🔴 حرج - مفتاح API ثابت ├── get.php .................... ⚠️ عالي ├── getWalletByDriver.php ...... ⚠️ عالي └── getDriverDetails.php ....... ⚠️ عالي ``` ### الفهم الحالي: ``` تطبيق السائق ↓ POST /add ← يضيف الأموال ↓ /walletintaleq.intaleq.xyz/v2/main/ride/driverWallet/add.php ↓ ← لا يوجد مصادقة! ❌ ``` ### الحل المقترح: (S2S - Server to Server) ``` تطبيق السائق ↓ POST /wallet/add (مع JWT توكن) ↓ BACKEND SERVER (backend/wallet/) ← نقطة جديدة ↓ • التحقق من JWT ✅ • فحص الملكية ✅ • التحقق من المبلغ ✅ ↓ POST /v2/main/ride/driverWallet/add (مع توقيع HMAC-SHA256) ↓ WalletIntaleq Server ↓ • التحقق من التوقيع ✅ • تنفيذ العملية ✅ • تسجيل دقيق ✅ ``` ### الخطوات العملية: #### 1️⃣ إنشاء endpoint في Backend ```php // backend/wallet/add.php (جديد) require_once __DIR__ . '/../core/bootstrap.php'; function requireAuth() { $headers = getallheaders(); $authHeader = $headers['Authorization'] ?? ''; if (!preg_match('/Bearer\s+(\S+)/', $authHeader, $matches)) { http_response_code(401); jsonError('Authentication required'); } $token = $matches[1]; $jwtService = new JwtService($redis); try { $decoded = $jwtService->verifyAccessToken($token); return $decoded; } catch (Exception $e) { http_response_code(401); jsonError('Invalid token'); } } try { $user = requireAuth(); // JWT verification // التحقق من الدور (التفويض) if ($user->role !== 'driver') { http_response_code(403); jsonError('Permission denied'); } $driverID = $user->id; $amount = floatval(filterRequest('amount')); $source = filterRequest('source'); // التحقق من المبلغ if ($amount <= 0 || $amount > 10000) { jsonError('Invalid amount (max 10,000)', 400); } // تحديد السرعة $limiter = new RateLimiter($redis); $limiter->enforce("wallet_add_{$driverID}", 'add', 1, 60); // 1 request per 60 seconds // تسجيل التدقيق $auditLog = "Driver {$driverID} requested to add {$amount} from {$source}"; securityLog($auditLog); // الاتصال بـ WalletIntaleq عبر S2S $walletResponse = callWalletAPI('add', [ 'driver_id' => $driverID, 'amount' => $amount, 'source' => $source, 'backend_request' => true, ]); if ($walletResponse['status'] === 'success') { jsonSuccess(['message' => 'تمت إضافة الأموال بنجاح']); } else { jsonError('Wallet operation failed', 500); } } catch (Exception $e) { securityLog("Wallet add error: " . $e->getMessage()); jsonError('Internal error', 500); } ``` #### 2️⃣ دالة S2S API call آمنة ```php // backend/core/WalletConnector.php (جديد) class WalletConnector { private $walletUrl = 'https://walletintaleq.intaleq.xyz/v2/main/'; private $hmacSecret = null; public function __construct() { $this->hmacSecret = getenv('WALLET_HMAC_SECRET'); if (!$this->hmacSecret) { throw new Exception("WALLET_HMAC_SECRET not configured"); } } public function call($endpoint, $data) { // إضافة timestamp لمنع Replay Attacks $data['timestamp'] = time(); $data['nonce'] = bin2hex(random_bytes(16)); // فرز البيانات وإنشاء signature ksort($data); $payload = json_encode($data); $signature = hash_hmac('sha256', $payload, $this->hmacSecret); // إرسال الطلب $ch = curl_init(); curl_setopt_array($ch, [ CURLOPT_URL => $this->walletUrl . $endpoint, CURLOPT_POST => true, CURLOPT_POSTFIELDS => $payload, CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ 'Content-Type: application/json', 'X-Signature: ' . $signature, 'X-Timestamp: ' . $data['timestamp'], 'X-Backend-ID: ' . getenv('BACKEND_ID'), ], CURLOPT_SSL_VERIFYPEER => true, CURLOPT_SSL_VERIFYHOST => 2, CURLOPT_TIMEOUT => 10, ]); $response = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); // التحقق من الاستجابة $decoded = json_decode($response, true); if ($httpCode !== 200 || $decoded['status'] !== 'success') { throw new Exception("Wallet API error: " . $response); } return $decoded; } } ``` #### 3️⃣ تعديل WalletIntaleq ```php // walletintaleq.intaleq.xyz/v2/main/ride/driverWallet/add.php 300) { // 5 دقائق http_response_code(401); jsonError('Request expired'); } // الآن آمن - نفذ العملية $driverID = $data['driver_id']; $amount = $data['amount']; $source = $data['source']; // أضف إلى قاعدة البيانات $stmt = $con->prepare( "INSERT INTO driverWallet (driver_id, amount, source, created_at, updated_at) VALUES (?, ?, ?, NOW(), NOW())" ); $stmt->execute([$driverID, $amount, $source]); // تسجيل التدقيق securityLog("Wallet added: Driver $driverID, Amount $amount from $source"); jsonSuccess(['message' => 'Added successfully']); } catch (Exception $e) { securityLog("Wallet error: " . $e->getMessage()); jsonError('Internal error', 500); } ?> ``` --- ## النقطة 5️⃣: أمان تطبيقات الهاتف - الأذونات ### الملف المتأثر: - `siro_driver/android/app/src/main/AndroidManifest.xml` ### الأذونات الحالية: ```xml ``` ### الفحص المطلوب: ```bash 1. بحث في codebase تطبيق السائق: grep -r "getExternalFilesDir\|getExternalCacheDir\|Environment.getExternalStorageDirectory" . إذا لم تظهر نتائج → احذف WRITE/READ_EXTERNAL_STORAGE 2. بحث عن SYSTEM_ALERT_WINDOW: grep -r "TYPE_APPLICATION_OVERLAY\|canDrawOverlays" . إذا لم تظهر → احذفها 3. بحث عن MODIFY_AUDIO_SETTINGS: grep -r "setVolume\|adjustStreamVolume" . إذا لم تظهر → احذفها ``` --- ## النقطة 6️⃣: load_env.php - تحميل آمن للمتغيرات ### الملف: - `backend/load_env.php` ### الحالة الحالية: ```php load(); ``` --- ## النقطة 7️⃣: backend/functions.php - الروابط الآمنة ### الحالة الحالية: ```php ❌ غير آمنة: $url = "http://188.68.36.205:2021"; $url = "http://188.68.36.205:3031"; $url = "https://location.intaleq.xyz"; ``` ### المشاكل: 1. **IP عام مكشوف** - 188.68.36.205 2. **HTTP بدل HTTPS** - عرضة لـ MITM attacks 3. **لا يوجد certificate pinning** ### الحل: ```php // ✅ الحل الآمن function getAllowedSocketUrls(): array { return [ 'https://location.siromove.com', // ✅ HTTPS + Domain 'https://socket.siromove.com', // ✅ HTTPS + Domain // لا HTTP ]; } function sendToLocationServer($action, $data) { $url = "https://location.siromove.com/api"; // تثبيت الشهادة (Certificate Pinning) $ch = curl_init(); curl_setopt_array($ch, [ CURLOPT_URL => $url, CURLOPT_POST => 1, CURLOPT_POSTFIELDS => http_build_query($data), CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 10, // ✅ تأمين SSL/TLS CURLOPT_SSL_VERIFYPEER => true, CURLOPT_SSL_VERIFYHOST => 2, CURLOPT_CAINFO => '/etc/ssl/certs/ca-bundle.crt', // ✅ Certificate Pinning (اختياري لكن موصى) // تحتاج حساب SHA-256 للشهادة CURLOPT_PINNEDPUBLICKEY => 'sha256/AAAA....', ]); $response = curl_exec($ch); curl_close($ch); return json_decode($response, true); } ``` --- ## ملخص الإصلاحات | النقطة | المشكلة | الحل | المدة | | ------ | ------------------ | ------------- | -------- | | 1 | بصمة ضعيفة | MFA + OTP | 8 ساعات | | 2 | IV ثابت | توليد عشوائي | 4 ساعات | | 3 | SQL Injection | آمن بالفعل ✅ | 0 ساعات | | 4 | المحفظة بلا مصادقة | S2S + JWT | 16 ساعات | | 5 | أذونات مفرطة | تقليص + فحص | 4 ساعات | | 6 | load_env.php | آمن بالفعل ✅ | 0 ساعات | | 7 | روابط HTTP | تبديل HTTPS | 2 ساعات | **المجموع:** ~34 ساعة --- ## التالي: 1. تطبيق الإصلاحات واحدة تلو الأخرى 2. اختبار كل إصلاح 3. ترحيل قاعدة البيانات 4. نشر للإنتاج