# دليل الإصلاحات الشامل - مشروع سيرو
**التاريخ:** 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. نشر للإنتاج