CVE-2025-27610 هي ثغرة أمنية عالية الخطورة في Rack::Static ضمن مكتبة Rack المستخدمة في تطبيقات Ruby. تسمح المشكلة، في ظروف محددة، بطلب ملفات لم يكن من المفترض أن تكون متاحة عبر المسارات المحددة في urls:، ما قد يؤدي إلى كشف ملفات موجودة داخل الدليل المحدد في root:.
كُشف عن الثغرة في مارس 2025 وصُنفت بدرجة 7.5 من 10 وفق CVSS 3.1. ولا تعني الثغرة تلقائيًا أن المهاجم يستطيع قراءة أي ملف موجود على نظام التشغيل؛ التأثير الموثق يتعلق بالملفات الموجودة تحت root: الذي يستخدمه Rack::Static. أصلحت Rack المشكلة في الإصدارات 2.2.13 و3.0.14 و3.1.12.
ما هي CVE-2025-27610؟
Rack هي طبقة أساسية في منظومة تطبيقات Ruby توفر واجهة موحدة بين تطبيق الويب وخادم HTTP ومكونات Middleware. ومن بين مكوناتها Rack::Static الذي يمكن استخدامه لتقديم ملفات ثابتة مثل CSS وJavaScript والصور.
على سبيل المثال، يمكن ضبط Rack::Static بحيث يقدم الملفات الموجودة تحت مسارات محددة:
use Rack::Static,
urls: ["/images", "/css"],
root: "public"
في هذا السيناريو، الهدف هو أن تُقدم الملفات الثابتة المطابقة للمسارات المحددة في urls: من الدليل public.
المشكلة في الإصدارات المتأثرة كانت مرتبطة بطريقة التعامل مع مسار الطلب. وفق التحذير الأمني الرسمي لمشروع Rack، لم تكن بعض مسارات المستخدم المرمزة تُنظف وتُتحقق منها بالشكل الصحيح قبل تقديم الملف. ونتيجة لذلك كان من الممكن تجاوز الحدود التي يتوقعها المطور من إعداد urls: والوصول إلى ملفات أخرى تحت root:.
ما الإصدارات المتأثرة؟
| فرع Rack | الإصدارات المتأثرة بـ CVE-2025-27610 | أول إصدار مصحح |
|---|---|---|
| 2.2.x | أقدم من 2.2.13 | 2.2.13 |
| 3.0.x | من 3.0.0 إلى ما قبل 3.0.14 | 3.0.14 |
| 3.1.x | من 3.1.0 إلى ما قبل 3.1.12 | 3.1.12 |
هذه الحدود موثقة أيضًا في السجل الرسمي للثغرة في NVD.
لكن هناك نقطة مهمة في 2026: الوصول إلى أحد هذه الإصدارات الدنيا لم يعد أفضل هدف للتحديث. فهو يزيل CVE-2025-27610 تحديدًا، لكنه لا يتضمن بالضرورة الإصلاحات الأمنية التي صدرت بعد مارس 2025.
ما الوضع الحالي لـ Rack في 2026؟
بحسب سياسة الدعم الحالية لمشروع Rack، يحصل فرع 3.2.x على إصلاحات الأخطاء والتحديثات الأمنية، بينما يحصل 3.1.x و2.2.x على تحديثات أمنية، وأصبح فرع 3.0.x خارج الدعم.
كما توصي وثائق المشروع مستخدمي 2.2.x بالانتقال إلى Rack 3.1 أو أحدث عندما يسمح توافق التطبيق بذلك.
وفي 13 أغسطس 2026، كان أحدث إصدار منشور على RubyGems هو Rack 3.2.7. لذلك يجب التعامل مع الإصدارات 2.2.13 و3.0.14 و3.1.12 على أنها الحدود التاريخية لإصلاح CVE-2025-27610، وليس بالضرورة الإصدارات التي ينبغي تثبيتها اليوم.
خصوصًا أن Rack تلقى تحديثات أمنية إضافية خلال 2025 و2026، بما فيها إصلاحات أخرى مرتبطة بتقديم الملفات ومعالجة الطلبات. لذلك فإن استراتيجية التحديث الأفضل هي الانتقال إلى أحدث إصدار آمن ومدعوم ومتوافق مع التطبيق بدل الاكتفاء بأول نسخة أغلقت هذه الثغرة.
كيف تعمل الثغرة تقنيًا؟
لفهم المشكلة، يجب التمييز بين urls: وroot:.
urls:تحدد المسارات التي يفترض أن يتعامل معهاRack::Static.root:يحدد الدليل الأساسي الذي تؤخذ منه الملفات.
وتوضح وثائق Rack::Static أن root: يستخدم الدليل الحالي Dir.pwd إذا لم يتم تحديده صراحة.
قبل التصحيح، كان الاختلاف في معالجة بعض المسارات المرمزة يسمح للطلب بتجاوز التقييد المتوقع في urls:. وبعد قبول الطلب، قد ينتهي Rack::Static إلى تقديم ملف آخر يقع تحت root:.
هذا يجعل اختيار root: مهمًا جدًا. فإذا كان يشير إلى دليل يحتوي فقط على أصول عامة، يكون نطاق البيانات الممكن كشفها محدودًا. أما إذا احتوى الدليل نفسه على ملفات لا يفترض نشرها، فقد تتحول الثغرة إلى تسريب معلومات حساس.
ما الذي يستطيع المهاجم الوصول إليه؟
يصف التحذير الرسمي التأثير بأنه إمكانية الوصول إلى الملفات الواقعة تحت root: إذا تمكن المهاجم من تحديد مسار الملف.
لذلك من المهم تصحيح تصور شائع عن CVE-2025-27610: الثغرة ليست تصريحًا عامًا لقراءة ملفات نظام التشغيل بالكامل. وجود ملف حساس خارج root: لا يعني أن هذه الثغرة وحدها تتيح قراءته.
يتوقف التأثير الفعلي على عوامل مثل:
- تشغيل إصدار متأثر من Rack.
- استخدام
Rack::Staticفي التطبيق. - إمكانية وصول المستخدم الخارجي إلى المسارات التي يعالجها Middleware.
- محتويات الدليل المستخدم كـ
root:. - قدرة المهاجم على معرفة أو استنتاج أسماء ومسارات الملفات الموجودة داخله.
إذا كان root: يحتوي على ملفات إعداد أو نسخ احتياطية أو بيانات أخرى غير مخصصة للنشر، يصبح تأثير كشف الملفات أكثر خطورة.
لماذا حصلت الثغرة على CVSS 7.5؟
سجل CVSS 3.1 المنشور للثغرة هو:
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N
ويعني ذلك أن سيناريو الثغرة الأساسي يتميز بما يلي:
- Network: يمكن تنفيذ الهجوم عبر الشبكة عندما تكون الواجهة المتأثرة قابلة للوصول.
- Low Attack Complexity: لا يفرض التقييم تعقيدًا مرتفعًا للهجوم.
- No Privileges Required: لا يتطلب السيناريو الأساسي حسابًا مصادقًا عليه.
- No User Interaction: لا يحتاج الضحية إلى تنفيذ إجراء.
- High Confidentiality Impact: الخطر الأساسي هو كشف المعلومات.
- No Integrity Impact: CVE-2025-27610 نفسها لا تمنح قدرة موثقة على تعديل البيانات.
- No Availability Impact: ليست في الأساس ثغرة لتعطيل الخدمة.
وهذا التفريق مهم؛ فوجود ثغرة بدرجة 7.5 لا يعني أنها تمنح المهاجم السيطرة الكاملة على الخادم.
لا تخلط CVE-2025-27610 بثغرات Rack الأخرى في 2025
كُشف خلال الفترة نفسها عن مشكلات أخرى في Rack، لكنها ثغرات مستقلة ولها تأثيرات مختلفة.
| CVE | المكون | نوع المشكلة |
|---|---|---|
| CVE-2025-27610 | Rack::Static |
كشف ملفات / Path Traversal |
| CVE-2025-27111 | Rack::Sendfile |
Log Injection |
| CVE-2025-25184 | Rack::CommonLogger |
Log Injection |
لذلك فإن التلاعب بالسجلات ليس التأثير الموثق لـ CVE-2025-27610، بل يرتبط بثغرات أخرى مثل CVE-2025-27111 في Rack::Sendfile وCVE-2025-25184 في Rack::CommonLogger.
كيف تعرف إصدار Rack المستخدم في تطبيقك؟
في التطبيقات التي تدير الاعتماديات باستخدام Bundler، يمكن التحقق من نسخة Rack الفعلية داخل المشروع بالأمر:
bundle info rack
ومن المفيد أيضًا مراجعة Gemfile.lock لأن وجود نسخة حديثة من Rack مثبتة على الجهاز لا يعني بالضرورة أن التطبيق يستخدمها. يقوم Bundler عادة بتشغيل النسخة المثبتة في ملف القفل الخاص بالمشروع.
بعد ذلك ابحث في إعدادات التطبيق عن استخدام:
Rack::Static
فوجود نسخة متأثرة من Rack لا يعني وحده أن التطبيق معرض لهذا المسار تحديدًا؛ يجب أيضًا أن يكون المكون المتأثر مستخدمًا بطريقة تجعل الطلبات الخارجية تصل إليه.
كيف تصلح CVE-2025-27610؟
1. حدّث Rack
إذا كان المشروع يستخدم Bundler، فغالبًا تتم إدارة التحديث من داخل المشروع بدل تثبيت Gem منفصلة على النظام. بعد مراجعة قيود الإصدار الموجودة في Gemfile يمكن تحديث الاعتمادية مثلًا باستخدام:
bundle update rack
يجب مراجعة التغييرات الناتجة في Gemfile.lock وتشغيل اختبارات التطبيق قبل نشر التحديث في بيئة الإنتاج.
إذا كانت قيود المشروع تمنع الإصدار المصحح، فيجب تحديث تلك القيود أو تحديث Framework أو الاعتمادية التي تفرض النسخة القديمة بدل الاكتفاء بتثبيت نسخة Rack أخرى خارج Bundle.
2. لا تعتمد على Rack 3.0 كحل طويل الأجل
الإصدار 3.0.14 أصلح CVE-2025-27610 تاريخيًا، لكن فرع 3.0.x أصبح الآن خارج الدعم وفق سياسة Rack الحالية. إذا كان التطبيق ما يزال يعتمد عليه، فالإجراء الأفضل هو وضع خطة انتقال إلى فرع مدعوم بعد اختبار التوافق.
3. احصر root في الملفات العامة فقط
إذا كان Rack::Static ضروريًا، فينبغي أن يشير root: إلى دليل مخصص حصريًا للمحتوى العام.
use Rack::Static,
urls: ["/images", "/css"],
root: "public"
لا تضع في الدليل نفسه أسرار التطبيق أو ملفات النسخ الاحتياطية أو ملفات إعداد البيئة أو أي بيانات لا يفترض أن تصبح متاحة عبر HTTP.
هذا مبدأ دفاعي مهم حتى بعد تثبيت التحديث، لأنه يقلل أثر أي خطأ مستقبلي يتعلق بتقديم الملفات.
4. أزل Rack::Static إذا لم تكن بحاجة إليه
يذكر التحذير الرسمي إزالة Rack::Static كأحد خيارات التخفيف عندما يتعذر التحديث فورًا. إذا كانت الملفات الثابتة تقدم أصلًا بواسطة خادم ويب أو خدمة أخرى، فقد لا تكون هناك حاجة إلى إبقاء Middleware داخل التطبيق.
5. يمكن تقديم الملفات الثابتة خارج تطبيق Ruby
يشير فريق Rack إلى أن استخدام CDN أو خادم ملفات ثابتة مماثل قد يخفف المشكلة. لكن هذا لا يكون فعالًا إذا بقي أصل التطبيق متاحًا مباشرة للإنترنت واستمر Rack::Static المتأثر في معالجة الطلبات.
يجب أن تكون بنية النشر نفسها ضامنة لعدم إمكانية تجاوز طبقة تقديم الملفات والوصول إلى المسار الضعيف في Origin.
هل يكفي جدار الحماية أو WAF بدل التحديث؟
لا. يمكن لـWAF أو Proxy أو قواعد المراقبة أن تقلل بعض المحاولات أو تساعد في اكتشافها، لكنها ليست بديلًا موثوقًا عن تثبيت الإصلاح.
المشكلة تقع داخل طريقة معالجة Rack للمسار. وقد تتغير أشكال ترميز URL، لذلك فإن الاعتماد على قاعدة تحاول اكتشاف كل شكل محتمل لمسار مشبوه يترك مجالًا للأخطاء والتجاوزات.
الأولوية هي إزالة النسخة الضعيفة أو تعطيل المكون المتأثر، ثم استخدام الطبقات الأخرى كدفاع إضافي.
كيف تتحقق من نجاح الإصلاح؟
بعد التحديث، لا يكفي نجاح أمر تثبيت الحزمة. نفذ عملية تحقق تشمل:
- تأكد من النسخة المستخدمة فعليًا بواسطة التطبيق عبر Bundler.
- راجع
Gemfile.lockبعد التحديث. - حدد جميع المواضع التي تستخدم
Rack::Static. - تأكد من أن
root:يحتوي فقط على الملفات التي يمكن نشرها. - اختبر أن المسارات المسموح بها ما زالت تقدم الملفات المطلوبة.
- اختبر أن الطلبات الخارجة عن نطاق الملفات العامة تُرفض ولا تعيد محتوى غير متوقع.
- راجع سجلات HTTP بحثًا عن محاولات غير اعتيادية للوصول إلى مسارات ملفات.
- شغّل اختبارات Regression قبل ترقية الإنتاج.
هل CVSS وحده يكفي لتحديد أولوية الإصلاح؟
درجة 7.5 تجعل CVE-2025-27610 مشكلة جدية، لكن أولوية المعالجة داخل مؤسسة تعتمد أيضًا على السياق: هل Rack::Static مستخدم فعلًا؟ هل التطبيق مكشوف للإنترنت؟ ماذا يحتوي root:؟ وهل توجد ضوابط تعويضية؟
هذا هو السبب في أن برامج إدارة المخاطر الحديثة لا تعتمد فقط على ترتيب CVEs حسب الدرجة، بل تربط الثغرة بالتعرض الفعلي ومسار الهجوم وقيمة الأصل. ويمكن فهم هذا النهج بصورة أوسع من خلال شرح إدارة التعرض المستمر CTEM.
ما حالة CVE-2025-27610 اليوم؟
CVE-2025-27610 ليست ثغرة جديدة في 2026؛ أُعلن عنها في مارس 2025 ويتوفر لها إصلاح منذ ذلك الوقت. كما أظهر تحديث بيانات NVD في يونيو 2026 أن تقييم CISA-ADP المرتبط بالسجل كان يحمل حالة exploitation: none، أي أن ذلك السجل لا يقدم دليلًا على استغلال نشط للثغرة.
لكن غياب دليل على الاستغلال النشط لا يجعل تشغيل نسخة متأثرة خيارًا آمنًا، خصوصًا أن الاستغلال الأساسي لا يتطلب مصادقة أو تفاعلًا من المستخدم وفق تقييم CVSS.
والأهم في 2026 أن بيئة Rack نفسها تطورت منذ اكتشاف CVE-2025-27610، وصدرت تحديثات أمنية لاحقة. لذلك ينبغي فحص Rack كاعتمادية مستمرة التحديث، لا التعامل مع الإصدار 2.2.13 أو 3.1.12 باعتباره نقطة نهاية دائمة.
الخلاصة
CVE-2025-27610 هي ثغرة Path Traversal في Rack::Static قد تسمح بكشف ملفات إضافية تحت root: بسبب معالجة غير صحيحة لبعض مسارات URL المرمزة. حصلت على CVSS 7.5 لأن السيناريو الموثق يمكن تنفيذه عبر الشبكة دون صلاحيات أو تفاعل من المستخدم، ويؤثر أساسًا في سرية البيانات.
أول الإصدارات التي أصلحت المشكلة كانت 2.2.13 و3.0.14 و3.1.12، لكن الاكتفاء بها في 2026 ليس الخيار الأفضل. استخدم إصدارًا حديثًا ومدعومًا ومتوافقًا مع تطبيقك، وتأكد من أن root: لا يحتوي إلا على ملفات عامة، وأزل Rack::Static إذا لم تكن بحاجة إليه، ثم اختبر التطبيق بعد التحديث للتأكد من إغلاق مسار التعرض دون التأثير في تقديم الملفات الشرعية.