ثغرتا PHP الحرجتان RCE: حدّث إلى 8.5.12 وما يخص Laravel

أصدر فريق PHP في 21 أكتوبر 2026 تحديثًا أمنيًا لـ PHP يعالج ثغرتين حرجتين من نوع RCE (تنفيذ أوامر عن بُعد) بدرجة CVSS 9.2 لكل منهما. إليك الإصدارات المصححة، وما معنى الثغرتين، وخطوات التحديث على Forge وCloud وVapor.

إذا كان تطبيق Laravel الخاص بك يعمل على أي خادم PHP يستقبل طلبات ويب، فهذا الخبر يخصك اليوم وليس لاحقًا. ما يميز هذا التحديث أن فريق PHP يقول إنه لا توجد حلول التفافية كاملة: التحديث هو العلاج الوحيد الكامل، وكل ما عداه تخفيف جزئي للمخاطر.

ما الذي حدث بالتحديد؟

في 20 أكتوبر أعلن فريق أمان PHP عن إصدار أمني مجدول يوم الأربعاء 21 أكتوبر الساعة 14:00 بتوقيت UTC، يعالج ثغرتين حرجتين دون كشف تفاصيلهما، مع الاحتفاظ بحق الإصدار المبكر إذا ظهرت تفاصيل علنية أو دلائل على استغلال فعلي. وفي اليوم التالي صدرت النسخ المصححة مع التفاصيل.

فرع PHPالنسخة المصححة
8.58.5.12
8.48.4.27
8.38.3.36
8.28.2.35

أما PHP 8.1 وما قبله فلم يعد يتلقى تحديثات رسمية من المشروع. بعض موزعي لينكس ومزودي الدعم الطويل (LTS) يوفرون backports، كما نشر الفريق backports مصدرية دنيا لـ PHP 7.4 و8.0 و8.1 لمن يبني PHP بنفسه. ويُذكر أن PHP 8.2 نفسه ينتهي دعمه في 31 ديسمبر 2026.

فهم ثغرتي PHP الحرجتين (RCE)

CVE-2026-109618: تلف الذاكرة عند نفاد الذاكرة (OOM)

عندما تنفد ذاكرة PHP، قد تُقاطَع العملية وبيانات الطلب الداخلية نصف مهيّأة فقط. بعد ذلك قد تتعامل خطوة تنظيف الطلب مع هذه البيانات غير الصالحة كأنها سليمة، ومن هنا يأتي احتمال تنفيذ الأوامر. المعرّف على GitHub هو GHSA-w8hw-w9fx-j79w.

CVE-2026-109619: حالة عامة قديمة (stale global state)

هنا تبقى حالة داخلية تخص طلبًا معينًا حيّة بعد تحرير الذاكرة التي تحتويها. وقد يستخدم طلب لاحق على نفس الـ worker هذه الحالة القديمة قبل أن تعيد التهيئة العادية ضبطها. المعرّف: GHSA-6wmf-4rv5-p3rp.

من المتأثر؟

كل تثبيت PHP يخدم طلبات ويب: PHP-FPM وApache مع mod_php وphp-cgi وFrankenPHP وLiteSpeed. يصنّف فريق PHP mod_php على أنه الأعلى خطرًا، لأن طلبًا غير موثّق يمكنه إطلاق الهجوم قبل أن يعمل أي كود من تطبيقك. وتذكر وثائق Forge أن الثغرتين تمتدان إلى نسخ PHP القديمة جدًا (منذ 2004 بحسب وصفها)، ولهذا لا يوجد إصدار قديم "آمن بحكم عمره".

لم تذكر المصادر التي راجعتها تفاصيل الاستغلال التقنية الكاملة، وهذا مقصود على الأرجح؛ التفاصيل موجودة في الـ advisories على GitHub.

ما الذي يجب أن تفعله الآن؟

الترتيب العملي:

  1. اعرف نسختك الحالية: نفّذ php -v (أو php8.4 -v لنسخة محددة) على كل خادم، وتحقق أيضًا من نسخ PHP الأخرى المثبتة وإن لم تستخدمها مواقعك.
  2. حدّث PHP إلى النسخة المصححة لفرعك عبر مدير الحزم أو مزود الاستضافة.
  3. أعد تشغيل العمليات طويلة العمر. تحديث الحزم يعيد تشغيل PHP-FPM، لكن العمليات التي بدأت من سطر الأوامر تبقى على النسخة القديمة إلى أن تُعاد: الـ queue workers وHorizon وOctane وReverb. تقترح وثائق Forge أوامر مثل:
php artisan queue:restart
php artisan horizon:terminate
php artisan octane:reload
  1. تحقق: شغّل php -v وphp-fpm8.4 -v (بحسب نسختك) وقارن الرقم بالجدول أعلاه.
  2. إذا كنت تستخدم Docker، فالصورة التي بنيتها سابقًا تحمل النسخة القديمة؛ أعد بناءها على صورة أساس محدّثة (هذا استنتاج مني وليس من نص الـ advisory).

وضع منصات Laravel

بحسب صفحة Laravel الرسمية (آخر تحديث لها وقت قراءتي: 21 أكتوبر 23:26 UTC، وهي تتغير باستمرار):

  • Laravel Cloud: رُقّعت كل التطبيقات العاملة في مكانها دون إعادة نشر، والنشر الجديد يستخدم صورًا محدّثة.
  • Laravel Forge: يلزم تدخل يدوي. اضغط "Update PHP" لكل خادم على PHP 8.2 إلى 8.5، أو حدّث عبر SSH. تنبّه وثائق Forge إلى أن التحديثات الأمنية التلقائية في Forge لا تشمل PHP، لأنه يُثبَّت من مستودع خاص. الخوادم على Ubuntu 20.04 أو أقدم لا يمكن ترقيعها، والمطلوب خادم جديد على نسخة مدعومة. ولا يوجد ترقيع لـ PHP 8.0 و8.1.
  • Laravel Vapor: الـ runtimes المرقّعة متاحة، لكن يجب إعادة نشر التطبيق. وإن كنت تستخدم runtime مخصصًا أو صورة Docker فالمطلوب نشر جديد وليس مجرد redeploy.
  • Laravel Envoyer: عاد للعمل وتعمل عمليات النشر، لكن فحوصات الصحة (health checks) لم تُستعد بعد وتحتاج تحديث PHP إضافيًا.

وإذا كنت تشغّل Node.js على نفس الخوادم فهناك إصدار أمني منفصل له في اليوم نفسه، وتذكّر Laravel بتحديثه يدويًا على خوادم Forge.

إذا لم تستطع التحديث فورًا: تخفيفات جزئية

يشدد فريق PHP على أن هذه الإعدادات تقلل التعرض لمسارات محددة ولا تجعل الخادم آمنًا. مثال مما نشره الفريق:

; php.ini أو إعدادات FPM pool (php_admin_value)
memory_limit = -1
post_max_size = 8M          ; 32M إن كنت تحتاج رفع ملفات
upload_max_filesize = 2M    ; يجب أن يبقى أقل من post_max_size
session.upload_progress.enabled = 0
; على PHP 8.5 فقط:
fatal_error_backtraces = 0

نقاط إضافية من الإعلان:

  • ضع memory_limit=-1 عبر php_admin_value حتى لا يستطيع التطبيق تجاوزه، وتأكد أن لا pool أو مجلد يعيد حدًا محدودًا.
  • فعّل حدودًا على الطلبات في خادم الويب أو الـ proxy (حجم الجسم، عدد الحقول، أجزاء multipart، الترويسات، عمق التداخل)، حتى للطلبات بلا Content-Length صالح.
  • استخدم حدًا للذاكرة على مستوى الحاوية أو cgroup يقتل الـ worker المتأثر فقط، وتجنب RLIMIT_AS وRLIMIT_DATA.
  • ضبط session.upload_progress.enabled=0 يجب أن يتم في php.ini أو إعدادات FPM أو الخادم ثم إعادة تشغيل كل الـ workers؛ فـ ini_set() وملفات .user.ini تأتي متأخرة جدًا.
  • إخفاء الأخطاء عبر error_reporting أو display_errors أو @ لا يفيد.
  • أصلح الأخطاء القاتلة (fatal errors) وانتهاءات المهلة التي يمكن للمهاجم الوصول إليها، كالـ callbacks ومعالجة الرفع والاستيراد.

لاحظ أن ضبط memory_limit=-1 يغيّر سلوك تطبيقك (تصبح أي حلقة تسرّب ذاكرة أخطر على الخادم)، لذا اجمعه مع حد على مستوى الحاوية، وأزل التخفيفات بعد التحديث.

الخلاصة

التحديث إلى 8.5.12 أو 8.4.27 أو 8.3.36 أو 8.2.35 أولوية اليوم، وليس مهمة الأسبوع القادم. على Cloud تم الأمر عنك، أما على Forge وVapor وخوادمك الخاصة فعليك التحرك بنفسك، ثم إعادة تشغيل الـ workers والتحقق بـ php -v. وإذا كنت على PHP 8.1 أو أقدم أو على Ubuntu 20.04، فهذه فرصة (بل ضرورة) للانتقال إلى نسخة مدعومة.

المصادر