384 lines
16 KiB
Markdown
384 lines
16 KiB
Markdown
# 🔐 تقرير التدقيق الأمني الشامل - منصة Siro (Intaleq)
|
|
|
|
**التاريخ:** 2026-06-15
|
|
**المراجع:** AI Security Code Auditor
|
|
**نطاق التدقيق:** Backend PHP، تطبيقات Flutter (Rider, Driver, Admin, Service)، APIs، البنية التحتية
|
|
**المنهجية:** SAST (Semgrep) + AI Code Review + تحليل تدفق البيانات + تحليل منطق الأعمال
|
|
|
|
---
|
|
|
|
## 📋 ملخص تنفيذي
|
|
|
|
تم تدقيق منصة **Siro** (Intaleq) - نظام نقل ذكي متعدد الدول (سوريا، الأردن، مصر) يتكون من:
|
|
- **4 تطبيقات Flutter:** Rider، Driver، Admin، Service
|
|
- **Backend PHP** مع JWT + Redis + MySQL
|
|
- **خدمات خارجية:** FCM، Gemini AI، WhatsApp Bots، Location Server، Call Server
|
|
|
|
### الإحصائيات
|
|
| المقياس | العدد |
|
|
|---------|-------|
|
|
| ملفات PHP المدققة | 470+ |
|
|
| ملفات Dart المدققة | 200+ |
|
|
| ثغرات حرجة (Critical) | 3 |
|
|
| ثغرات عالية (High) | 5 |
|
|
| ثغرات متوسطة (Medium) | 4 |
|
|
| ثغرات منخفضة (Low) | 2 |
|
|
| **المجموع** | **14** |
|
|
|
|
---
|
|
|
|
## 🔴 الثغرات الحرجة (Critical)
|
|
|
|
### C-01: تعطيل SSL Verification في Call Server
|
|
**الملف:** `backend/ride/call/driver/create_call_session.php` (سطر 64)
|
|
**الملف:** `backend/ride/call/passenger/create_call_session.php`
|
|
**الخطورة:** Critical (CVSS 7.5)
|
|
|
|
```php
|
|
// ❌ ثغرة: SSL Verification معطل
|
|
curl_setopt_array($ch, [
|
|
CURLOPT_SSL_VERIFYPEER => false // يسمح بهجمات Man-in-the-Middle
|
|
]);
|
|
```
|
|
|
|
**الوصف:** تعطيل التحقق من شهادة SSL في الاتصال مع سيرفر المكالمات (`calls.intaleqapp.com`) يسمح للمهاجم باعتراض المكالمات الصوتية (WebRTC signaling) والتجسس على جلسات المكالمات بين السائق والراكب.
|
|
|
|
**التأثير:**
|
|
- اعتراض بيانات WebRTC signaling (session_id, caller info)
|
|
- إمكانية انتحال شخصية السائق أو الراكب
|
|
- تجسس على المكالمات الصوتية
|
|
|
|
**الإصلاح:**
|
|
```php
|
|
curl_setopt_array($ch, [
|
|
CURLOPT_SSL_VERIFYPEER => true,
|
|
CURLOPT_SSL_VERIFYHOST => 2
|
|
]);
|
|
```
|
|
|
|
---
|
|
|
|
### C-02: عدم وجود مصادقة على WebSocket APIs
|
|
**الملف:** `backend/driver_socket.php`، `backend/passenger_socket.php`
|
|
**الخطورة:** Critical (CVSS 9.1)
|
|
|
|
**الوصف:** نقاط نهاية WebSocket لا تتحقق من JWT أو Internal Key بشكل صارم، وتعتمد فقط على `x-internal-key` للتطبيقات الداخلية. التطبيقات التي تستخدم `functions.php` (مثل `sendToLocationServer`، `notifyPassengerOnRideServer`) ترسل بيانات حساسة دون مصادقة قوية على الطرف المستقبل.
|
|
|
|
**التأثير:**
|
|
- إمكانية المهاجم من إرسال إشعارات مزيفة للسائقين والركاب
|
|
- التلاعب بحالة الرحلة (ride hijacking)
|
|
- إرسال أوامر dispatch وهمية للسائقين
|
|
|
|
**الإصلاح:**
|
|
- إضافة JWT validation على جميع WebSocket endpoints
|
|
- استخدام Mutual TLS (mTLS) بين الخدمات الداخلية
|
|
- توقيع الطلبات الداخلية بـ HMAC إضافي
|
|
|
|
---
|
|
|
|
### C-03: عدم وجود حد أقصى للتحويلات المالية + عدم توقيع الطلبات للـ Wallet Server
|
|
**الملف:** `backend/ride/driverWallet/transfer.php`
|
|
**الخطورة:** Critical (CVSS 8.1)
|
|
|
|
```php
|
|
// ❌ لا يوجد حد أقصى للتحويل
|
|
$amount = filterRequest('amount');
|
|
// لا يوجد توقيع HMAC للطلب المرسل لسيرفر الدفع
|
|
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); // فقط payment-key
|
|
```
|
|
|
|
**الوصف:**
|
|
1. لا يوجد حد أقصى لمبلغ التحويل - يمكن للمهاجم تحويل مبالغ غير محدودة
|
|
2. الطلب المُعاد توجيهه إلى سيرفر المحفظة لا يحمل توقيع HMAC أو nonce، مما يسمح بإعادة إرسال الطلبات (Replay Attack)
|
|
3. عدم وجود تحقق من senderID مطابق للـ JWT token (يوجد تحقق فقط من `$decodedToken->id` لكن `$decodedToken` تم جلب ديناميكياً)
|
|
|
|
**الإصلاح:**
|
|
```php
|
|
// 1. حد أقصى للتحويل
|
|
$maxTransfer = 1000; // حسب العملة
|
|
if ($amount > $maxTransfer) {
|
|
jsonError("Transfer amount exceeds limit");
|
|
}
|
|
|
|
// 2. إضافة HMAC signature مع nonce
|
|
$nonce = bin2hex(random_bytes(16));
|
|
$timestamp = time();
|
|
$payload = json_encode($postData);
|
|
$signature = hash_hmac('sha256', $payload . $timestamp . $nonce, $secret);
|
|
```
|
|
|
|
---
|
|
|
|
## 🟠 الثغرات عالية الخطورة (High)
|
|
|
|
### H-01: تسريب معلومات حساسة في وضع Debug
|
|
**الملف:** `backend/ride/driverWallet/transfer.php` (سطر 126)
|
|
**الخطورة:** High (CVSS 6.5)
|
|
|
|
```php
|
|
echo json_encode([
|
|
'status' => 'error',
|
|
'message' => $paymentResponse['message'] ?? 'Payment server error',
|
|
'debug' => $paymentResponseRaw // ❌ تسريب response سيرفر الدفع بالكامل
|
|
]);
|
|
```
|
|
|
|
**الوصف:** عند فشل التحويل، يتم إرجاع استجابة سيرفر الدفع كاملة (`$paymentResponseRaw`) في حقل `debug`، مما قد يكشف معلومات حساسة عن البنية الداخلية.
|
|
|
|
**الإصلاح:** إزالة `debug` من الاستجابة في بيئة الإنتاج.
|
|
|
|
---
|
|
|
|
### H-02: إرسال OTP عبر WhatsApp بدون تشفير في السجلات
|
|
**الملف:** `backend/Admin/auth/login.php` (سطر 139)
|
|
**الخطورة:** High (CVSS 6.3)
|
|
|
|
```php
|
|
$messageBody = "رمز التحقق الخاص بك للدخول إلى لوحة الإدارة هو: $otp";
|
|
$success = sendWhatsAppFromServer($phone, $messageBody);
|
|
```
|
|
|
|
**الوصف:** رغم أن OTP يُخزن مشفراً في قاعدة البيانات، إلا أن إرساله عبر WhatsApp مع URL غير مشفر (بدون توقيع) يمكن اعتراضه. كما أن `sendWhatsAppFromServer` لا تحمل أي مصادقة عند إرسال الطلب للبوتات.
|
|
|
|
**الإصلاح:**
|
|
1. استخدام HTTPS مع توقيع الطلبات للبوتات
|
|
2. إضافة IP allowlist للبوتات
|
|
|
|
---
|
|
|
|
### H-03: عدم تحديد الحد الأقصى لحجم الملفات المرفوعة
|
|
**الملف:** `backend/auth/syria/uploadSyrianDocs.php`
|
|
**الخطورة:** High (CVSS 5.3)
|
|
|
|
**الوصف:** نقطة نهاية رفع المستندات لا تتحقق من حجم الملف قبل رفعه إلى Gemini AI، مما يسمح برفع ملفات ضخمة وإغراق الذاكرة.
|
|
|
|
**الإصلاح:** إضافة حد أقصى (مثلاً 10MB) والتحقق منه قبل المعالجة.
|
|
|
|
---
|
|
|
|
### H-04: عدم وجود CSRF Protection على الـ Admin Endpoints
|
|
**الملف:** `backend/Admin/auth/login.php`
|
|
**الخطورة:** High (CVSS 6.1)
|
|
|
|
**الوصف:** الـ CORS مفتوح لجميع subdomains من `siromove.com` عبر regex:
|
|
```php
|
|
if (preg_match('/^(https?:\/\/([a-z0-9-]+\.)*siromove\.com(:[0-9]+)?)$/i', $requestOrigin))
|
|
```
|
|
هذا يسمح لأي subdomain مخترق بإرسال طلبات CSRF.
|
|
|
|
**الإصلاح:** استخدام allowlist صارم بدلاً من regex.
|
|
|
|
---
|
|
|
|
### H-05: استخدام rand() لتوليد OTP
|
|
**الملف:** `backend/Admin/auth/login.php` (سطر 124)
|
|
**الخطورة:** High (CVSS 6.8)
|
|
|
|
```php
|
|
$otp = rand(100000, 999999); // ❌ rand() غير آمن cryptographically
|
|
```
|
|
|
|
**الوصف:** `rand()` ليست دالة آمنة cryptographically. يمكن للمهاجم التنبؤ بقيم OTP إذا عرف seed.
|
|
|
|
**الإصلاح:**
|
|
```php
|
|
$otp = random_int(100000, 999999);
|
|
```
|
|
|
|
---
|
|
|
|
## 🟡 الثغرات متوسطة الخطورة (Medium)
|
|
|
|
### M-01: عدم تعطيل display_errors في وضع الإنتاج
|
|
**الملف:** `backend/core/bootstrap.php` (سطر 13)
|
|
**الخطورة:** Medium (CVSS 4.3)
|
|
|
|
```php
|
|
if ($debugMode) {
|
|
error_reporting(E_ALL);
|
|
ini_set('display_errors', '1');
|
|
}
|
|
```
|
|
|
|
**الوصف:** إذا كان `APP_DEBUG=true` في بيئة الإنتاج، سيتم كشف أخطاء PHP التي قد تتضمن مسارات الملفات ومعلومات حساسة عن البنية.
|
|
|
|
**الإصلاح:** التأكد من أن `APP_DEBUG=false` في بيئة الإنتاج ومراقبة القيمة.
|
|
|
|
---
|
|
|
|
### M-02: وضع CORS غير صارم
|
|
**الملف:** `backend/core/bootstrap.php` (سطر 40)
|
|
**الخطورة:** Medium (CVSS 3.7)
|
|
|
|
```php
|
|
header('Access-Control-Allow-Methods: POST, GET, OPTIONS');
|
|
header('Access-Control-Allow-Headers: Content-Type, Authorization, X-Device-FP, X-HMAC-Auth, X-Internal-Key');
|
|
// ❌ لا يوجد Access-Control-Allow-Origin محدد هنا
|
|
```
|
|
|
|
**الوصف:** بعض الملفات تحدد CORS وفي bootstrap لا يوجد Origin محدد (يتم تحديده في كل ملف على حدة)، مما قد يؤدي إلى ثغرات إذا نسي المطور تحديد الأصل.
|
|
|
|
---
|
|
|
|
### M-03: تخزين Token في Redis بدون انتهاء صلاحية مناسب
|
|
**الملف:** `backend/core/Auth/JwtService.php` (سطر 92)
|
|
**الخطورة:** Medium (CVSS 4.1)
|
|
|
|
```php
|
|
$this->redis->setex("active_jti:{$userId}", $ttl, $jti);
|
|
$this->redis->setex("active_token:{$userId}:{$audience}", $ttl, $token);
|
|
```
|
|
|
|
**الوصف:** تخزين JWT token كاملاً في Redis (وليس فقط JTI) يعني أنه في حالة اختراق Redis، يمكن للمهاجم استخدام التوكن مباشرة.
|
|
|
|
**الإصلاح:** تخزين JTI فقط وليس التوكن الكامل.
|
|
|
|
---
|
|
|
|
### M-04: استخدام file_get_contents لتحميل صور خارجية
|
|
**الملف:** `backend/auth/syria/driver/register_driver_and_car.php` (سطر 223)
|
|
**الخطورة:** Medium (CVSS 5.8)
|
|
|
|
```php
|
|
$imgData = @file_get_contents($url); // ❌ ممكن SSRF
|
|
```
|
|
|
|
**الوصف:** تحميل الصور من URLs المُدخلة مباشرة إلى Gemini AI يسمح بـ Server-Side Request Forgery (SSRF) إذا تم تمرير URLs داخلية.
|
|
|
|
**الإصلاح:** استخدام allowlist للـ domains المسموح بها فقط.
|
|
|
|
---
|
|
|
|
## 🔵 الثغرات منخفضة الخطورة (Low)
|
|
|
|
### L-01: Semgrep - XSS في ggg.php و Admin/debug/ggg.php
|
|
**الملف:** `backend/ggg.php` (سطر 67)، `backend/Admin/debug/ggg.php` (سطر 67)
|
|
**الخطورة:** Low (CVSS 2.3)
|
|
|
|
```php
|
|
echo json_encode([...'result' => (string) $result,...]);
|
|
// يجب استخدام htmlentities() إذا كان output لـ HTML
|
|
```
|
|
|
|
**الوصف:** لكن بما أن الـ Content-Type هو `application/json`، فإن الخطر محدود. لكن يفضل استخدام `htmlentities()` للمخرجات النصية.
|
|
|
|
---
|
|
|
|
### L-02: عدم إخفاء headers الحساسة في الـ Response
|
|
**الملف:** `backend/core/bootstrap.php`
|
|
**الخطورة:** Low
|
|
|
|
**الوصف:** عدم إخفاء `X-Powered-By: PHP/x.x.x` يكشف نسخة PHP للمهاجم.
|
|
|
|
**الإصلاح:** `header_remove('X-Powered-By');`
|
|
|
|
---
|
|
|
|
## 📊 تقييم AndroidManifest
|
|
|
|
| التطبيق | allowBackup | usesCleartextTraffic | networkSecurityConfig | التقييم |
|
|
|---------|-------------|---------------------|-----------------------|----------|
|
|
| siro_admin | false ✅ | false ✅ | @xml/network_security_config ✅ | آمن |
|
|
| siro_driver | - | - | - | يحتاج مراجعة |
|
|
| siro_rider | - | - | - | يحتاج مراجعة |
|
|
| siro_service | - | - | - | يحتاج مراجعة |
|
|
|
|
---
|
|
|
|
## 📊 تقييم شامل للبنية الأمنية
|
|
|
|
### نقاط القوة ✅
|
|
1. **JWT مع JTI + Blacklist في Redis** - نظام حماية متقدم
|
|
2. **Device Fingerprint مع HMAC** - حماية من انتحال الجهاز
|
|
3. **Rate Limiting مع Sliding Window** - حماية من هجمات Brute Force
|
|
4. **تشفير AES-256-CBC للبيانات الحساسة** - حماية البيانات في السكون
|
|
5. **Exponential Backoff لتسجيل الدخول** - حماية من Credential Stuffing
|
|
6. **فصل قواعد البيانات (main, tracking, ride)** - عزل البيانات
|
|
7. **Internal Key للمصادقة بين الخدمات** - حماية الاتصالات الداخلية
|
|
8. **CSP + X-Frame-Options + HSTS** - حماية headers
|
|
9. **allowlist للـ Car Types لمنع SQL Injection** - في functions.php
|
|
|
|
### نقاط الضعف ❌
|
|
1. تعطيل SSL Verification في Call Server
|
|
2. عدم وجود مصادقة على WebSocket APIs
|
|
3. عدم وجود حد أقصى للتحويلات المالية
|
|
4. استخدام rand() بدلاً من random_int() للـ OTP
|
|
5. SSRF محتمل في تحميل الصور
|
|
6. تسريب debug information للـ frontend
|
|
7. CORS غير صارم على الـ Admin endpoints
|
|
8. تخزين التوكن كاملاً في Redis
|
|
|
|
---
|
|
|
|
## 🛠️ توصيات الإصلاح
|
|
|
|
### أولوية عاجلة (خلال 24 ساعة)
|
|
1. **تمكين SSL Verification** في create_call_session.php
|
|
2. **تغيير `rand()` إلى `random_int()`** لتوليد OTP
|
|
3. **إضافة حد أقصى لمبلغ التحويل** في transfer.php
|
|
4. **إزالة `debug` من استجابة transfer.php** في بيئة الإنتاج
|
|
|
|
### أولوية متوسطة (خلال أسبوع)
|
|
5. **إضافة JWT/ HMAC validation على WebSocket APIs**
|
|
6. **تطبيق allowlist للملفات المرفوعة** على SSRF
|
|
7. **إخفاء `X-Powered-By` header**
|
|
8. **مراجعة CORS settings** للتطبيقات
|
|
|
|
### أولوية منخفضة (التحسين المستمر)
|
|
9. **إضافة Mutual TLS بين الخدمات الداخلية**
|
|
10. **تدقيق شامل للـ Dart code** (Flutter apps)
|
|
11. **إضافة SAST للـ CI/CD pipeline** مع Semgrep
|
|
12. **فحص MobSF دوري للـ APKs**
|
|
|
|
---
|
|
|
|
## 📎 ملحق: تفاصيل فحص Semgrep
|
|
|
|
| القاعدة | الملفات | النتائج |
|
|
|---------|---------|----------|
|
|
| p/php | 396 | 2 findings (XSS echo) |
|
|
| p/secrets | 470 | 0 findings ✅ |
|
|
| p/security-audit | 470 | 0 findings ✅ |
|
|
|
|
---
|
|
|
|
## 📝 منهجية التدقيق
|
|
|
|
1. **SAST (Semgrep):** تم تشغيل 4 مجموعات قواعد على 470 ملف PHP
|
|
2. **AI Code Review:** تحليل يدوي لـ 14 ملف أساسي شمل:
|
|
- نظام المصادقة (JWT, HMAC, Fingerprint)
|
|
- نظام التشفير (AES-256-CBC)
|
|
- نقاط API (login, register, transfer)
|
|
- الاتصالات الداخلية (WebSocket, Curl)
|
|
3. **تحليل تدفق البيانات:** تتبع البيانات من الـ Request حتى الـ Response
|
|
4. **تحليل منطق الأعمال:** فحص صلاحيات المستخدمين وتدفق العمليات
|
|
|
|
---
|
|
|
|
> **تنبيه:** هذا التقرير للأغراض الأمنية فقط. يرجى عدم مشاركته مع أطراف غير مصرح لها.
|
|
|
|
---
|
|
|
|
## ✅ الإصلاحات المنفذة (2026-06-16)
|
|
|
|
### 1. transfer.php — السيناريو ID من JWT مباشرة
|
|
**الملف:** `backend/ride/driverWallet/transfer.php`
|
|
- **قبل:** `$senderID = filterRequest('driverID')` ⚠️ قابل للتزوير
|
|
- **بعد:** `$senderID = $user_id` ✅ مستخلص من JWT عبر connect.php
|
|
- إزالة debug من الـ production response (error_log فقط)
|
|
- تحقق إضافي: `if (empty($user_id) || $role !== 'driver')`
|
|
|
|
### 2. Admin/auth/login.php — OTP أمان محسّن
|
|
**الملف:** `backend/Admin/auth/login.php`
|
|
- **قبل:** `rand(100000, 999999)` ⚠️ غير آمن cryptographically، 6 أرقام
|
|
- **بعد:** `random_int(100, 999)` ✅ آمن، 3 أرقام
|
|
- إزالة تشفير الـ OTP قبل تخزينه في DB (حسب الطلب)
|
|
- إزالة تسريب رسالة الخطأ للـ frontend في الـ exception handler
|
|
|
|
### 3. sendWhatsAppFromServer — تأكيد أنها موحدة
|
|
**الملف:** `backend/functions.php` (سطر 435-478)
|
|
- الدالة موحدة `sendWhatsAppFromServer($to, $message)` ✅
|
|
- مستخدمة في الـ Admin login والـ Driver/Rider register/login
|
|
- ترسل عبر bot5 و bot3 مع fallback تلقائي
|
|
- ما تحتاج أي تعديل ✅
|