صفر بيانات اعتماد على الورق. حساب واحد في الواقع.
صفر. هذا عدد بيانات الاعتماد التي يتطلبها متجه CVSS الخاص بـGitLab نفسها لثغرة CVE-2026-97229: AV:N/AC:L/PR:N/UI:N، تقييم كامل 10.0، تنفيذ شيفرة عشوائية دون أي صلاحيات. واحد. هذا عدد الحسابات التي احتاجها الشخصان الوحيدان اللذان أنجحا هذا الاستغلال فعلاً، كلٌّ بشكل مستقل، قبل أن يتمكنا من إرسال الطلب الذي فعل شيئاً فعلاً. كلا الرقمين صحيح. إنهما يصفان خطوتين مختلفتين في الهجوم نفسه.
ثغرة CVE-2026-97229 هي فيضان عدد صحيح حرج في محرّك التعبيرات النمطية لـCI/CD في GitLab، أُصلحت في 12 أكتوبر 2026 عبر الفروع 19.2 و19.3 و19.4.[1] تنبيه GitLab نفسه يصف بالضبط ما يعنيه ذلك التقييم: تعبير نمطي مُصاغ خصيصاً داخل إعداد CI/CD، يُرسله مستخدم غير مُصادَق، يتحول إلى تنفيذ شيفرة عشوائية على الخادم تحت شروط معينة.[1] وبعد أقل من ثلاثة أسابيع، أضافتها CISA إلى فهرس الثغرات المُستغَلّة المعروفة، مؤكدة أنها تُستخدم ضد أهداف حقيقية.[2] لا شيء من هذا خاطئ. إنه فقط يتجاهل التفصيل الوحيد الذي يوضح لك مدى تعرّضك الفعلي: الوصول إلى الخطوة غير المُصادَقة يتطلب حساباً أولاً.
ما الذي أصدرته GitLab فعلاً، وفي أي وقت
حدّدت GitLab تاريخ إصدار الإصلاح في 12 أكتوبر 2026، بإصدار 19.2.8 و19.3.5 و19.4.2 للفروع الثلاثة المتأثرة: 19.2 قبل 19.2.8، و19.3 قبل 19.3.5، و19.4 قبل 19.4.2.[1] كانت GitLab.com تعمل بالفعل على نسخة مُصلَّحة قبل نشر التنبيه، ولم يكن على عملاء GitLab Dedicated فعل أي شيء.[1] استخدم الباحث الذي أبلغ عن الثغرة اسم المستخدم joaxcar على HackerOne، وأبلغ بشكل منفصل عن ثغرة إعادة توجيه مفتوح متوسطة الخطورة، CVE-2026-7767، أُصلحت في الإصدار نفسه.[1]
تغيّر تفصيل واحد بعد نشر الإصدار، ويستحق معرفته قبل أن تتحقق من رقم إصدارك. أشارت ملاحظات إصدار GitLab في البداية إلى أن فرع 19.3 أُصلح في 19.3.4؛ وذكرت تقارير في اليوم التالي أن تلك النسخة أصلحت في الواقع خللاً غير مرتبط بصفحات طلبات الدمج، وأن 19.3.5 هو الإصدار المُصلِح الحقيقي لهذه الثغرة، وهو ما يعكسه التنبيه الحالي الآن.[8] بعد ذلك، تحرّكت الأمور بسرعة: أفادت Rapid7 بإعادة إنتاج عملية ناجحة ومستقلة بعد يوم تقريباً من الإفصاح، تلاه إثبات مفهوم علني موقَّع باسم كاتبه بعد أربعة أيام تقريباً، ثم أدرجته CISA في قائمة الاستغلال المؤكد بعد نحو سبعة عشر يوماً من الإصلاح الأصلي.[1][2][4][7] هذا ليس الموضوع الأساسي لهذا المقال. لكنه يستحق التوقف عنده: ثغرة بتقييم CVSS كامل 10.0 في منتج بحجم GitLab تُسلَّح بسرعة بمجرد أن يُرشد الإصلاح نفسه المهاجمين إلى أين ينظرون.
محرّك التعبيرات النمطية الذي ينفّذ أمرك بدل مطابقة سلسلتك
لم أُعِد إنتاج هذا بنفسي. كل ما يلي مبنيّ على إثبات المفهوم الذي نشره Jonah Burgess (على GitHub: jburgess-r7) بعد نحو أربعة أيام من الإصلاح، ووصفه صريحاً بأنه «إصدار أولي لإثبات المفهوم»، وعلى إعادة الإنتاج التي أفادت بها Rapid7 بشكل منفصل، وعلى تنبيه GitLab نفسه، وجميعها مقروءة حتى 2 نوفمبر 2026.[1][3][4] يكمن المُحفِّز خلف نقطة CI-lint في GitLab، وهي النقطة نفسها التي تستخدمها GitLab للتحقق من ملف .gitlab-ci.yml قبل تشغيل أي خط أنابيب. زوّدها بتعبير نمطي مُصاغ خصيصاً داخل إعداد CI/CD، مع فرع في المستودع يستخدم مساره حيلة تسمية معينة بترميز UTF-8، فيفيض حساب الطول الداخلي لمحرّك التعبيرات النمطية.[3]
هذا الفيضان لا يُسقط العامل (worker) فقط، رغم أنه كثيراً ما يفعل ذلك أيضاً. إنه يُعيد توجيه تنفيذ محرّك التعبيرات النمطية إلى وجهة أخرى، مباشرة إلى دالة تُنفّذ أمراً عشوائياً.[3] يعمل الأمر باسم حساب الخدمة محدود الصلاحيات «git» في GitLab، لا باسم مسؤول ولا بصلاحيات root على الخادم المضيف.[3] هذا سقف حقيقي لحجم الضرر، ويستحق أن يُقال بوضوح: هذا تنفيذ شيفرة من جهة الخادم، لا طريق فوري للسيطرة الإدارية الكاملة. ومع ذلك، من داخل شِل «git»، يملك المهاجم فعلاً ما يستحق الحصول عليه، بدءاً من محتوى المستودعات وأي أسرار CI يمكن لهذا الحساب قراءتها.
// The CI-lint trigger, reconstructed from Burgess's public PoC. Paraphrased
// shape of the chain -- not the working payload itself.
1. Attacker-controlled branch is pushed to a public project, with a
specially-named (UTF-8) path and a crafted regex in .gitlab-ci.yml.
2. An unauthenticated request hits GitLab's CI-lint endpoint, which
validates that regex before any pipeline actually runs.
3. The regex compiler's internal length accounting overflows -- an
integer wraps where it shouldn't.
4. Execution inside the regex engine is redirected into a function that
runs an OS command, as the low-privilege "git" service account.
5. On a vulnerable build, the worker process frequently crashes right
after (a bare HTTP 502 is a side effect, not proof by itself).الخطوة التي تحدث قبل الخطوة غير المُصادَقة
هذا هو التفصيل الذي يتجاهله كل عنوان عن CVSS 10. يذكر README الخاص بـBurgess الشروط المسبقة بوضوح: حساب عادي قادر على رفع (push) فرع إلى مشروع عام على النسخة المستهدفة؛ هدف يعمل على البناء الرسمي تحديداً gitlab/gitlab-ce:19.4.1-ce.0 (أي بناء آخر يحتاج إزاحات ثنائية مُعاد بناؤها)؛ نحو 9 جيجابايت من الذاكرة المتاحة؛ وإمكانية وصول شبكي إلى مستمع إذا أردت ناتج الأمر.[3] أما طلب CI-lint الذي يُشغّل الفيضان فعلاً، فلا يحتاج أي رمز مصادقة أو كوكي أو ترويسة تفويض على الإطلاق، وهذا الجزء بالفعل غير مُصادَق.[3][4] إنه فقط ليس الخطوة الأولى.
وفقاً لتقرير Help Net Security، أعادت Rapid7 بشكل مستقل إنتاج تنفيذ شيفرة فعّال ضد نسخة رسمية غير مُصلَحة من GitLab CE 19.4.1 بعد نحو يوم من الإفصاح (وفشل الإدخال نفسه على النسخة المُصلَحة 19.4.2)، ووصفت العائق نفسه: «حساب عادي» يرفع الفرع المُصاغ خصيصاً، وهو قابل للتطبيق «على النسخ ذاتية الإدارة التي تسمح بإنشاء مشاريع عامة».[4] جهتان مستقلتان، عملت كل منهما بمفردها، وتوصلتا إلى الشرط المسبق نفسه. سأشير إلى أمر لا تذكره السجلات صريحاً، لأن دمجهما أمر مُغرٍ: اسم مستخدم GitHub لإثبات المفهوم يحمل لاحقة «-r7»، وReadme نفسه يحيل إلى «التحليل التقني لـRapid7» لهذه الثغرة نفسها. لا يذكر أي مصدر هذا الارتباط صراحة، لذا أتعامل مع إثبات مفهوم Burgess وإعادة إنتاج Rapid7 كما تُظهره السجلات فعلاً: تأكيدان مستقلان للشرط المسبق نفسه، لا تأكيداً واحداً.
كاتب إثبات المفهوم صريح أيضاً بشأن حدوده: نجحت 10 من 10 محاولات على تلك النسخة الوحيدة المُختبَرة مع تفعيل ASLR، ويعيد الإدخال نفسه نتيجة false على مُجمِّع 19.4.2 المُصلَح، ويذكر الكاتب صراحة أن «تحليل الإعدادات المتأثرة الأخرى والمسارات القابلة للوصول لا يزال مستمراً»، وأن إثبات المفهوم «لا يثبت استغلالاً حقيقياً في اختراقات فعلية».[3] وكثيراً ما يُعيد التشغيل الناجح استجابة HTTP 502 بسيطة، لأن العامل ينهار مباشرة بعد تنفيذ الأمر، لذا فإن استجابة 502 وحدها، دون بقية النمط، لا تُثبت شيئاً.[3] احتفظ بهذا الفرق في ذهنك. فهو مهم لما يمكنك استنتاجه فعلاً من سجلاتك الخاصة.
إلى أي مدى يمتد «عدم المصادقة» فعلاً
فأيّ الوصفين صحيح: غير مُصادَقة أم لا؟ كلاهما، حسب الحدّ الذي تسأل عنه. يُقيّم متجه CVSS من GitLab المكوّن الثغرة بـPR:N، أي لا صلاحيات مطلوبة، وهذا دقيق تماماً لما يُقيَّم فعلاً: طلب CI-lint نفسه لا يتحقق من أي بيانات اعتماد.[1] لكن «المكوّن لا يتطلب مصادقة» و«سلسلة الهجوم لا تتطلب مصادقة» ادعاءان مختلفان، والجهتان الوحيدتان المُسمَّيتان اللتان أنجحتا هذا فعلياً، Burgess وRapid7، تتفقان بشكل مستقل على أن السلسلة تحتاج خطوة قبل ذلك الطلب: حساباً قادراً على رفع فرع إلى مشروع عام.[3][4] تقييم الخطورة من GitLab ليس خاطئاً. إنه يجيب فقط عن سؤال أضيق مما يُلمّح إليه العنوان.
ويعتمد كون هذا الشرط المسبق تافهاً أو عائقاً حقيقياً على إعدادات لا يراها معظم المسؤولين كتدابير تخفيف لهذه الثغرة. تقول وثائق GitLab نفسها إن التسجيل الذاتي مفتوح لأي زائر افتراضياً على نسخة ذاتية الإدارة، وتوصي بتعطيله على أي نسخة متاحة للإنترنت لا تتوقع تسجيلاً مفتوحاً.[5] وتقول أيضاً إن موافقة المسؤول على التسجيلات الجديدة هي الإعداد الافتراضي للنسخ الجديدة منذ GitLab 13.6، أي أن نسخة حديثة ومُهيَّأة بشكل معقول لديها فعلاً إنسان في الحلقة قبل أن يحصل غريب على حساب.[5] أما رؤية المشاريع، ومن يُسمح له بإنشاء مشروع عام، فهي إعدادات أخرى يتحكم بها المسؤول بشكل منفصل.[5] لا شيء من هذا تصحيح للثغرة. لكن كل ذلك يغيّر عدد الغرباء الذين يمكنهم أصلاً الوصول إلى النصف غير المُصادَق من هذه الثغرة.
// For a stranger to turn this into RCE against your instance,
// three things have to be true at once:
1. Your instance allows self-registration, OR the attacker already
holds any ordinary account on it.
2. That account (or self-registration) can create, or push a branch
to, a PUBLIC project -- not just a private one.
3. The instance is still running an unpatched build
(before 19.2.8 / 19.3.5 / 19.4.2) and is reachable from wherever
the attacker is.
Close registration, restrict who can make projects public, or patch --
any one of the three breaks the chain. Patching is still the only fix
that doesn't depend on a setting staying the way you left it.استغلال مؤكَّد. وتأكيد شبه معدوم لأي شيء آخر.
أضافت CISA ثغرة CVE-2026-97229 إلى فهرس الثغرات المُستغَلّة المعروفة في 29 أكتوبر 2026، تحت اسم «GitLab Community Edition and Enterprise Edition Integer Overflow or Wraparound Vulnerability»، مع تاريخ استحقاق للإجراء المطلوب في 1 نوفمبر بموجب التوجيه الملزم BOD 26-04.[2] تاريخ الإضافة هذا ليس ادعاءً بشأن متى بدأ الاستغلال فعلاً. فسجلات KEV تتأخر غالباً عن أول استخدام حقيقي في الواقع، ولا يذكر أي مصدر هنا متى بدأت الهجمات على هذه الثغرة فعلياً. اقرأ «29 أكتوبر» كتاريخ تأكيد CISA للأمر، لا كتوقيت للهجمات نفسها.
هذا هو الحجم الصريح لما يعنيه «استغلال مؤكَّد» في هذا السجل، ويستحق الدقة لأن السجل أرقّ بكثير مما يُلمّح إليه العنوان: لا يُنشر في أي مصدر رُوجع لهذا المقال، لا سجل CISA نفسه، ولا تنبيه GitLab، ولا تقرير BleepingComputer عنها، أي مؤشر اختراق، أو ضحية مُسمَّاة، أو وصف على مستوى التقنية للهجمات المرصودة فعلاً.[1][2][6] يستشهد تقرير BleepingComputer اللاحق بإصدارات GitLab الخاصة بالكشف عن التهديدات وبعدد Shadowserver لنحو 2800 نسخة من GitLab CE مكشوفة على الإنترنت، وهذا هو كل التفاصيل العامة المتاحة.[6] يرتكز «استغلال مؤكَّد» هنا على سجل CISA كمصدر موثوق مُسمًّى، لا على دليل هجوم كان يمكن لهذا المقال فحصه بشكل مستقل. هذا أساس مشروع لهذا التحديد. وهو أيضاً السقف الأقصى لما يمكنني قوله لك بصدق عن الهجمات نفسها.
الإصلاح، القواعد، وما يجب فحصه هذا الأسبوع
الإصلاح مُحدَّد بدقة بالإصدارات: 19.2.8 و19.3.5 و19.4.2، جميعها صدرت في 12 أكتوبر 2026.[1] إذا كان فرع 19.3 لديك يُظهر 19.3.4، فتلك النسخة أصلحت خللاً غير مرتبط بصفحات طلبات الدمج، لا هذه الثغرة؛ 19.3.5 هو ما تحتاجه فعلاً.[8] إلى جانب الإصلاح، أصدرت GitLab ستة قواعد جديدة للكشف عن التهديدات للنسخ ذاتية الإدارة، مُسمَّاة خصيصاً لهذه المشكلة: Onigmo native worker crash، وGraphQL cilint hostile regexp، وci regexp oversized non-ascii path، وci regexp guard rejection، وci lint workhorse worker crash، وci lint scripted client error burst.[1] إذا رصد نظام المراقبة الخاص بك أو أدوات الكشف من GitLab أياً من هذه، فاعتبره إشارة تستحق التتبّع، لا ضجيجاً.
تنشر سياسة الإفصاح الخاصة بـGitLab التفاصيل الكاملة في متتبّع المشكلات لثغرة مُصلَحة بعد 90 يوماً من إصدار الإصلاح، وهذا بحسابٍ بسيط يضع أي تفاصيل تتجاوز نص التنبيه قرب منتصف يناير 2027، وهذا ليس تاريخاً تذكره GitLab نفسها، بل مجرد ما تؤدي إليه قاعدتها الخاصة بالتسعين يوماً.[1] حتى ذلك الحين، هذا ما يدعمه السجل العلني فعلاً للفحص.
Patch and verify, in order:
[ ] Confirm the build actually RUNNING, not just what the changelog
says: 19.2.8 / 19.3.5 / 19.4.2 or later.
[ ] If self-managed, review sign-up restrictions: is self-registration
open, and is admin approval of new accounts actually enabled?
[ ] Review who can create or push to a PUBLIC project on your instance
-- that setting is the other half of this bug's real exposure.
[ ] Enable and watch GitLab's six named threat detections for this CVE,
especially "ci lint workhorse worker crash" and "ci regexp guard
rejection".
[ ] Check CI-lint access logs for requests with no auth header paired
with recently-pushed branches on public projects -- that pairing
is this chain's fingerprint, a bare HTTP 502 is not.تقييم CVSS يُقيّم الثغرة. لا يُقيّم نسختك.
ثغرة CVE-2026-97229 ثغرة حرجة حقيقية، وتقييمات الخطورة من GitLab وCISA كلاهما صحيح. ما لا يستطيع الرقم وحده قوله لك هو إن كانت نسختك من النوع المفتوح على مصراعيه الذي بُنيت هذه السلسلة من أجله، أو من النوع الذي يكون فيه التسجيل مغلقاً ورؤية المشاريع مقيَّدة. والنسخة الثانية هدف أصغر بشكل ملموس، حتى بالنسبة لثغرة بتقييم CVSS 10.0 ومُستغَلّة فعلياً. تقييم الخطورة يُقيّم مكوّناً. أما التعرّض فخاصية في إعداداتك، ولا أحد يُقيّمها عنك.
هذه بالضبط الثغرة التي أبحث عنها في مراجعة تطبيق ويب أو خط أنابيب CI/CD: ليس فقط «هل هذا مُصلَح»، بل «بالنظر إلى كيفية إعداد هذه النسخة فعلاً، ماذا يمنح النصف غير المُصادَق من ثغرة معيّنة للمهاجم هنا فعلاً». إن كنت تشغّل GitLab ذاتي الإدارة، أو أي سطح CI/CD يحتوي أجزاءً متاحة للإنترنت، وتفضّل أن يتفحّص أحد هذا الحدّ معك بدل الاعتماد فقط على كلمة تقييم CVSS، فهذا هو نوع التقييم الذي أقدّمه. أخبرني كيف تُعدّ نسختك فعلاً، ونحدّد معاً نطاق العمل.
المصادر
- [1] GitLab: تنبيه إصدار الإصلاح الحرج لثغرة CVE-2026-97229
- [2] CISA: سجل فهرس الثغرات المُستغَلّة المعروفة
- [3] Jonah Burgess (GitHub): إثبات المفهوم وReadme لثغرة CVE-2026-97229
- [4] Help Net Security: إعادة إنتاج Rapid7 المستقلة
- [5] GitLab: وثائق قيود التسجيل
- [6] BleepingComputer: CISA تؤكد الاستغلال النشط
- [7] Cyber Security News: أول تغطية علنية لإثبات المفهوم
- [8] Dualmedia: تصحيح الإصدار من 19.3.4 إلى 19.3.5
هل تحتاج إلى هذا الفحص في منتجك؟
اختبار اختراق الويب وواجهات APIهل تريد أن تتعلم اكتشاف ثغرات كهذه بنفسك؟
دورة اختبار اختراق تطبيقات الويب بتدريب فردي