اقرأ هذا أولاً: إطار المقال وحدوده كُتب هذا المقال لأغراض تعليمية ودفاعية. فهو لا يشرح كيفية تنفيذ هجوم ولا يتضمن أي شيفرة استغلال. الوقائع المذكورة هي المعروفة في 25 أكتوبر 2026، أي بعد أربعة أيام من صدور التصحيحات، وقد تتغير بسرعة. كل ادعاء مهم يحيل إلى مصدره؛ وعندما يكون المصدر من طرف ثالث أو غير رسمي، أو حين لم أستطع التحقق من نقطة ما، أذكر ذلك صراحة.
لماذا تستحق PHP2Shell اهتمامنا
في 21 أكتوبر 2026 نشر مشروع PHP إشعاراً أمنياً وصفه بالحرج، يتعلق بثغرتين هما CVE-2026-109618 وCVE-2026-109619، وقد تتيحان لمهاجم غير موثَّق تنفيذ تعليمات برمجية على الخادم. يُعرف الزوج باسم «PHP2Shell»، وهو الاسم الذي أطلقه باحثو شركة Calif على أداة الاستغلال؛ وبحسب مقالهم فقد اكتشفوا الثغرتين مع OpenAI وWiz. وتحيل ملاحظات مشروع PHP وسجل Debian الأمني إلى الاسم نفسه.
بدلاً من الحديث عن زلزال عالمي، لنلتزم بالوقائع. الثابت أن مشروع PHP نفسه يقول إن «جميع تثبيتات PHP التي تخدم طلبات الويب» معنيّة، وإن الخطر أعلى ما يكون مع Apache وmod_php. وتصنّف Red Hat المسألة مهمة وتشير إلى أن تنفيذ التعليمات في النشر الافتراضي عبر PHP-FPM يبقى «صعباً عملياً». أما شركة الأمن Sansec فترى في تحليلها (مصدر من طرف ثالث) أن الاستغلال الواسع أقل احتمالاً مما كان يُخشى، لأن أدوات الاستغلال العامة التي فحصتها لا تعمل على تثبيت افتراضي، لكنها تنقل أيضاً هجمات مبكرة أبلغت عنها Cloudflare يوم الإصدار. فالخطر حقيقي ومتفاوت بحسب الإعداد، والتصحيح هو الحل الكامل الوحيد.
لماذا يكون تنفيذ الأوامر على الخادم خطيراً إلى هذا الحد؟ لأنه يمنح المهاجم صلاحيات عملية الويب: قراءة ملفات التطبيق وأسراره (كلمات مرور قواعد البيانات ومفاتيح الواجهات البرمجية)، وتعديل الموقع، ثم الانتقال إلى أنظمة أخرى في الشبكة الداخلية. وما يفصل بين حادثة يمكن احتواؤها واختراق دائم هو سرعة الإصلاح وحسن عزل الصلاحيات.
الجزء 1: PHP2Shell للمبتدئين، فهم المشكلة
ما الذي تعنيه PHP2Shell
إنها عيبان في إدارة الذاكرة داخل محرك PHP، وليست عيباً في تطبيق بعينه. وPHP ليست «ضعيفة بطبيعتها»: فالعيبان في نواة اللغة (المحرك الذي ينفّذ سكربتاتك)، وقد صُحّحا في إصدارات محددة. بحسب الإشعارات الرسمية:
- CVE-2026-109618 (إشعار GHSA): تستخدم PHP قفزة غير محلية (
longjmp()) للخروج الاضطراري عند فشل حجز الذاكرة. فإن حدث ذلك بينما البيانات الداخلية للطلب نصف مهيّأة، فإن التنظيف في نهاية الطلب يقرأ حالة غير صالحة. - CVE-2026-109619 (إشعار GHSA): قد تبقى حالة داخلية تخص طلباً ما حيّة بعد تحرير الذاكرة المرتبطة بها. وعندها قد تستخدمها عملية لاحقة في العملية نفسها («استخدام بعد التحرير»، use after free) قبل أن تستبدلها التهيئة العادية.
وبحسب المصادر الثانوية التي راجعتها، نالت الثغرتان درجة 9.2 وفق CVSS v4.0 (لم أتحقق من هذه الدرجة لدى الجهة المخوّلة بإصدار المعرّفات).
كيف يعمل الطلب في الحالة العادية
يرسل المتصفح طلب HTTP. يستقبله خادم الويب (Apache وnginx...) ويسلّمه إلى PHP: إما بتنفيذها داخل العملية نفسها (mod_php، وهي وحدة في Apache)، وإما بتمريره إلى خدمة منفصلة (PHP-FPM عبر FastCGI). وقبل أن تُنفَّذ شيفرتك أصلاً، تحلّل PHP جسم الطلب (النماذج والملفات المرفوعة) لملء $_POST و$_FILES. وبعد إنتاج الاستجابة تنظّف PHP ذاكرة الطلب وتنتقل العملية إلى الطلب التالي. هذه الدورة «بدء، تحليل، تنفيذ، تنظيف» هي ما تخلّ به الثغرتان.
الآلية دون شيفرة
يصف باحثو Calif المنطق في مقالهم:
- إحداث نفاد ذاكرة متحكَّم به. تحدّ PHP الذاكرة لكل طلب (
memory_limit، وقيمتها الافتراضية 128 ميغابايت). وطلب من نوعmultipart/form-data(صيغة رفع الملفات) يمكنه، بحقول متداخلة أو أجزاء فارغة، أن يجعل PHP تستهلك ذاكرة داخلية أكبر بكثير من حجمه على الشبكة، مع بقائه تحتpost_max_size. ويضيف الإشعار الرسمي الأجسام التي لا تحمل طولاً معلناً صالحاً للاستخدام، والأجزاء ذات العدد غير المحدود من الترويسات. - مقاطعة PHP في اللحظة الخطأ. فشل الحجز يدفع PHP إلى الخروج الاضطراري في منتصف عملية، دون تنفيذ «الترتيب» المقرر.
- ترك حالة غير متسقة. بحسب الإشعار الرسمي، ومع mod_php، تُنفَّذ مرحلة إنهاء الطلب حتى لو فشل البدء، فتعالج هذه الحالة غير الصالحة. ويحدث ذلك كله قبل تنفيذ شيفرة التطبيق: فالتطبيق السليم تماماً لا يحميك.
- استغلال عدم الاتساق. مع تحضير دقيق للذاكرة (heap) قد يتحول عدم الاتساق إلى تنفيذ تعليمات.
وبحسب الإشعار، يبدو PHP-FPM في وضع أفضل: إذ تنتهي عملية الابن عند فشل البدء، فلا تُستهلك الحالة غير الصالحة. لكن تحليل الشيفرة المصدرية يُبقي PHP-FPM «عرضة» عبر مسارات أخرى، دون أن يُثبت استغلال كامل لهذا النمط. ويُرجَّح أن يكون FrankenPHP عرضة مثل mod_php، وLSAPI مثل FPM (تحليل مصدري لم يُتحقق منه باستغلال فعلي).
من يلعب أي دور؟ شيفرة PHP (تطبيقك) ليست سبب المشكلة. والمحرك (Zend) يحمل العيب. وقد تتدخل الإضافات: فالمسار الأكثر توثيقاً لـ CVE-2026-109619 يمر بميزة تتبّع تقدم الرفع في إضافة session (session.upload_progress). وتكامل خادم الويب (mod_php أو FPM) يحدد الخطورة. أما نظام التشغيل فلا يعنينا إلا في النهاية بوصفه الضحية: تُنفَّذ الأوامر بصلاحيات مستخدم عملية الويب.
وفيما يخص دوال تنفيذ الأوامر مثل system() وexec()، لا يجعل شيء في المصادر التي راجعتها تفعيلها شرطاً للهجوم: فتنفيذ التعليمات ناتج عن إفساد الذاكرة وليس عن سوء استخدام هذه الدوال. وتعطيلها (disable_functions) يبقى ممارسة جيدة عامة، لكن ليس لدي مصدر يثبت أنه يمنع هذا الهجوم. فلا تعتمد عليه.
النتائج المحتملة
تتوقف على الصلاحيات والإعداد: قراءة الملفات والأسرار المتاحة لمستخدم الويب، والعبث بالتطبيق، وزرع باب خلفي، والانتقال إلى أجهزة أخرى. وتذكر Calif أنها أكدت تنفيذ التعليمات قبل المصادقة على عدة تطبيقات معروفة (WordPress وDrupal وJoomla وMagento وNextcloud وLaravel وغيرها، بإصداراتها الحديثة): فالتطبيق ليس هو الثغرة، لكنه لا يحميك منها.
وقائع متنازع عليها أو بحاجة إلى تدقيق تكتب Calif أن الاستغلال «ممكن دائماً مع الإعدادات الافتراضية»؛ وتفيد Sansec بأن أدوات الاستغلال العامة التي اختبرتها لا تعمل على تثبيت افتراضي؛ وتشير PHP إلى mod_php بوصفه الحالة التي ثبت استغلالها. هذه العبارات ليست متناقضة (مسارات وشروط مسبقة مختلفة)، لكن عليك الحذر: الإعداد الافتراضي ليس حماية.
الجزء 2: كيف تقيّم تعرّضك
1. تحديد إصدار PHP ومصدره
php -v # command-line version
php -i | grep -E "Server API|memory_limit|post_max_size|session.upload_progress.enabled"
rpm -q php-common # RHEL, AlmaLinux, CentOS (distribution or Remi package)
dpkg -l 'php*' | grep ^ii # Debian, Ubuntu
انتبه: سطر الأوامر لا يستخدم بالضرورة ملف php.ini نفسه الذي يستخدمه خادم الويب. ولمعرفة ما تراه الخدمة فعلاً، استعلم عنها في سياقها (مثلاً صفحة تشخيص مؤقتة ومحمية تُحذف بعد الاستعمال) أو اقرأ إعداد مجمّع FPM والمضيف الافتراضي.
دوّن كذلك المصدر: حزمة التوزيعة، أو مستودع من طرف ثالث، أو صورة Docker، أو ملفات Windows التنفيذية، أو بناء محلي. فهو الذي يحدد أين تبحث عن التصحيح.
2. تحديد نمط التشغيل
apachectl -M | grep php (وحدة Apache)، systemctl status php*-fpm (FPM)، ووجود php-cgi أو FrankenPHP أو LiteSpeed. وكما رأينا، فإن mod_php هو الحالة الأكثر تعرضاً بحسب PHP.
3. المقارنة بالتصحيحات المؤكدة
| الفرع | الحالة بحسب php.net | الإصدار المصحَّح الرسمي |
|---|---|---|
| 8.5 | مدعوم | 8.5.12 |
| 8.4 | مدعوم | 8.4.27 |
| 8.3 | مدعوم | 8.3.36 |
| 8.2 | مدعوم | 8.2.35 |
| 8.1 و8.0 و7.4 | انتهى عمره | لا إصدار منشور؛ فروع تصحيح أدنى بالمصدر (انظر الجزء 4) |
| 7.3 وما قبله | انتهى عمره | لا شيء رسمي |
تعدّ إشعارات GHSA كل الإصدارات الأقدم من هذه الأرقام الأربعة متأثرة. وتضع Calif أقدم مسار وجدته عند PHP 5.4.0.
فخ شائع: في حزم التوزيعات، لا يتغير رقم الإصدار دائماً. فالحزمة المصحَّحة قد تعرض 8.1.34 وهي تحتوي التصحيح. تحقق من سجل تغييرات الحزمة (الطريقة التي ذكرتها Sansec، مصدر من طرف ثالث):
# Debian, Ubuntu (adapt the version)
zgrep CVE-2026-109618 /usr/share/doc/php8.2-common/changelog.Debian.gz
# RHEL, AlmaLinux, Rocky
rpm -q --changelog php-common | grep CVE-2026-109618
حتى هذا الفحص له حد: فهو يثبت أن المسؤول عن الحزمة يقول إنه عالج الثغرة، لا أن التصحيح كامل أو مطابق لتصحيح مشروع PHP (انظر الجزء 4).
4. ماسح كشف أم أداة إثبات استغلال؟
ماسح الكشف يبحث عن مؤشرات (الإصدار المعلن، سلوك ملحوظ). أما أداة إثبات الاستغلال فتثبت إمكانية تنفيذ تعليمات. لا تخلط بينهما، ولا تشغّل أياً منهما على نظام لا تملكه.
قرأتُ شيفرة php2shell-scanner الذي نشره فريق أبحاث Assetnote (Searchlight)، وهو ينسب الاكتشاف إلى Calif. ما تفعله الشيفرة فعلاً:
- يرسل طلباً شاهداً ثم حتى ثلاثة طلبات
multipartمفخَّخة (حقول متداخلة على 62 مستوى، من 1 إلى 20 ميبيبايت)، أي نحو 29 ميبيبايت في المجموع لكل مسار مفحوص. - يحكم بأنه «ضعيف» عند خطأ ذاكرة في PHP، أو استجابة HTTP 500 فارغة تفاضلية، أو تعطل عامل PHP-FPM، أو إصدار معلن معروف بأنه غير مصحَّح.
- هو لا يثبت الاستغلال: إنه يلاحظ سلوكاً.
وحدوده، كما يقر بها ملف README الخاص به:
- إيجابيات كاذبة: في بعض الإعدادات (قيمة
memory_limitمنخفضة، أوmax_multipart_body_partsمرتفعة)، يعطي الإصدار المصحَّح الاستجابة نفسها التي يعطيها الإصدار الضعيف. - سلبيات كاذبة: عدم حدوث تعطل ليس ضماناً. فالفحص عن بُعد لا يرى الإعداد الداخلي ولا المسارات الأخرى (سكربتات أخرى، مضيفات افتراضية أخرى).
- الإصدارات المنقولة تصحيحياً (backport): بحسب الشيفرة، يُحكم بأن الإصدار المعلن الأدنى من 8.2 والذي لا تصحيح رسمياً له ضعيف. فالحزمة المنقول إليها التصحيح (وما زالت تعلن 7.4.33) تُصنَّف خطأً «ضعيفة» إن كشفت PHP إصدارها.
- الأثر على الشبكة: هو اختبار نشط قد يقتل عاملاً أو يستنفد الذاكرة. فاقصره على أنظمتك، خارج أوقات الذروة، وبموافقة داخلية.
قاعدة بسيطة: الفحص مؤشر وليس حكماً. غياب النتيجة لا يثبت شيئاً؛ والنتيجة الإيجابية على إصدار منقول إليه التصحيح تُتحقق بطريقة أخرى (سجل الحزمة، اختبار سلوك في مختبر).
الجزء 3: حلول إصلاح المشكلة
لكل استراتيجية: متى تناسب، ومتطلباتها، ومزاياها وحدودها، وفحوص ما بعد النشر. فحوص مشتركة بين الجميع: إعادة تشغيل كل العاملين (FPM وApache)، والتحقق من الإصدار المحمَّل فعلاً في الخدمة، وإعادة اختبارات التطبيق، ومراقبة سجلات الأخطاء.
PHP من 8.2 إلى 8.5 (الفروع المدعومة)
- متى: دائماً، إن سمح التطبيق.
- المتطلبات: حزمة أو ملف تنفيذي بالإصدار 8.2.35 أو 8.3.36 أو 8.4.27 أو 8.5.12 على الأقل.
- المزايا: تصحيح رسمي مدعوم، دون اعتماد على طرف ثالث.
- الحدود: تغيير الفرع (من 8.3 إلى 8.4) ترحيل له عدم توافقاته. والانتقال إلى PHP 8 لا يصلح شيئاً بحد ذاته: فPHP 8.0 و8.1 متأثرتان أيضاً. والإصدارات 8.2.35 و8.3.36 و8.4.27 و8.5.12 (أو الأحدث) وحدها تحتوي التصحيح الرسمي.
- الفحوص:
php -vمن جهة الخدمة، واختبار تحميل الإضافات، واختبارات رفع الملفات.
يستبدل التصحيح الرسمي قفزة longjmp() بخروج أنظف: توقف «ناعم» عند أقرب نقطة آمنة في الآلة الافتراضية، وتوقف فوري إن بلغ الاستهلاك عتبة ثانية أعلى (إشعار GHSA). فهو يعالج العيب بدل إخفائه.
PHP 7.x و8.0 و8.1 (فروع انتهى عمرها)
بحسب PHP، لم تعد هذه الفروع تتلقى تحديثات المشروع، لكن فريق الأمن نشر تصحيحات دنيا بالمصدر للفروع 7.4 و8.0 و8.1: PHP-7.4-CVE-2026-109618-109619 وPHP-8.0-... وPHP-8.1-.... وهي شيفرة مصدرية، دون أرشيف أو ملف تنفيذي أو تغيير في رقم الإصدار.
أما 7.3 وما قبله (5.x و7.0 إلى 7.3) فلم أجد لها أي تصحيح رسمي. ويقدّم أطراف ثالثة تصحيحات لها (انظر الجزء 4)، ومطابقتها للتصحيح الرسمي يجب إثباتها لا افتراضها.
- متى: حين يتعذر الترحيل على المدى القريب.
- المتطلبات: إما مورّد ينقل التصحيحات إلى الإصدارات القديمة، وإما مهارة في البناء.
- الحدود: التوافر يتوقف على المكوّن والمسؤول عن الصيانة وقناة التوزيع؛ ولا يوجد تصحيح تلقائي.
- الفحوص: انظر الجزء 4.
Debian
بحسب سجل Debian الأمني (اطّلعتُ عليه في 25 أكتوبر 2026): صُحّح Debian 12 bookworm (php8.2) في 8.2.35-1~deb12u1 (DLA-4848-1)؛ وصُحّح Debian 13 trixie (php8.4) في 8.4.27-1~deb13u1 (DSA-6574-1). وبالنسبة لـ Debian 11 (php7.4)، فالخيط الوحيد الذي وجدته هو الدعم الممتد المدفوع لدى Freexian (ELTS)، وفق بحث على الويب لم أعد التحقق منه في صفحة المورّد.
- متى: خوادم Debian التي تستخدم حزم التوزيعة.
- المتطلبات:
apt update && apt upgrade، ومستودعsecurityمفعَّل. - المزايا: تصحيح مدمج، وتحديثات يمكن أتمتتها.
- الحدود: إصدارات PHP مجمّدة بقرار التوزيعة؛ وقد يكون دعم إصدار قديم مدفوعاً أو غائباً. ويقدّم مستودع deb.sury.org (من Ondřej Surý) إصدارات أقدم بحسب Sansec: قيّمه كأي مستودع من طرف ثالث (الجزء 4).
- الفحوص:
apt list --installed 'php*'، وسجل التغييرات، وإعادة تشغيل FPM أو Apache.
CentOS وأنظمة RHEL المتوافقة
تنشر Red Hat النشرة RHSB-2026-013 (نُشرت في 21 أكتوبر 2026 وحُدّثت في 23 منه). وتعدّ RHEL 7 و8 و9 و10 معنيّة. وثمة تفصيل لافت: في PHP المرفقة بـ RHEL 7، تذكر Red Hat أن الشيفرة الضعيفة الخاصة بـ CVE-2026-109618 غير موجودة، وأن CVE-2026-109619 وحدها تنطبق. وهذا لا يصح إلا على PHP الخاصة بـ Red Hat: فإصدار PHP 7.4 من مستودع طرف ثالث (Remi مثلاً) برنامج مختلف، يُعالج بحسب مورّده. وبحسب Sansec، يقدّم Remi تصحيحات للإصدارات 7.4 و8.0 و8.1.
ونقطة الحذر هي انتهاء عمر التوزيعات: لم يعد المشروع يصون CentOS 7؛ ولا يغطي RHEL 7 إلا دعم ممتد مدفوع. واستخدام توزيعة قديمة يعني غالباً الاعتماد على طرف ثالث من أجل PHP. وعلى AlmaLinux أو Rocky، راجع نشرات التصحيح الخاصة بإصدارك.
- الفحوص:
rpm -q --changelog php-common | grep CVE-2026-109618، وإصدار الحزمة ونسختها (release)، وإعادة تشغيل الخدمات.
Windows
تقول PHP إن مصادر الإصدارات المصحَّحة وملفاتها التنفيذية لـ Windows موجودة في صفحة التنزيل، أي للفروع من 8.2 إلى 8.5. ولم أجد أي ملف تنفيذي رسمي مصحَّح لـ Windows للإصدار 8.1 وما قبله.
- الإجراء العام: حدد مصدر ملفاتك التنفيذية الحالية (php.net، أو حزمة WAMP/XAMPP، أو مثبّت من مورّد)، ونزّل الإصدار المصحَّح، وتحقق من التوقيع أو البصمة المنشورة، وأوقف IIS أو Apache، واستبدل مجلد PHP مع الاحتفاظ بنسخة من القديم ومن
php.ini، ثم أعد التشغيل. - الحدود: الحزم المتكاملة تضم PHP خاصة بها، بجدولها الزمني.
- الفحوص:
php -vوphp --iniللمجلد الصحيح، وصفحة تشخيص الخدمة.
Docker
تُعاد بناء صورة php الرسمية للفروع المدعومة (بحسب مصادر من أطراف ثالثة، في غضون ساعات من الإصدار)، وبحسب Sansec لا تصحيح مقرراً للإصدار 8.1 وما قبله في الصور الرسمية.
- متى: التطبيقات المعبّأة في حاويات.
- المتطلبات: وسم حديث (
php:8.4-fpmبالإصدار 8.4.27 أو أحدث)، وإعادة بناء الصورة (docker build --pull --no-cache)، وتحديث الطبقات السفلية، وإعادة نشر كل الحاويات، بما فيها تلك التي تعمل منذ شهور. - الحدود: صورة «محدّثة» لا تُعاد نشرها تبقى ضعيفة. والوسم المتحرك مريح لكنه قليل التتبّع: ثبّت البصمة (digest) بعد المصادقة.
- الفحوص:
docker run --rm <image> php -v، وجرد الصور في الإنتاج، والبحث عن الحاويات المبنية على وسوم قديمة.
الجزء 4: حين يتعذر رفع الإصدار
يتوجه هذا الجزء إلى الفرق التي تصون تطبيقات قديمة (توافق، أو اعتماد، أو تكلفة، أو تبعيات، أو عقود). القرار الأول هو معرفة من ينتج التصحيح.
| مصدر التصحيح | ما هو | ما يمكن التحقق منه |
|---|---|---|
| المسؤول الرسمي عن الصيانة | إصدار ينشره مشروع PHP (8.2.35 وما بعده) | توقيعات الإصدار، وإشعارات GHSA |
| تصحيح المشروع بالمصدر | فروع PHP-7.4 و8.0 و8.1 «CVE-2026-109618-109619»، دون إصدار أو ملف تنفيذي | الفرق (diff) العلني، ويجب أن تبنيه بنفسك |
| النقل التصحيحي (backport) | طرف ثالث (توزيعة، أو Remi، أو مورّد LTS) يكيّف التصحيح مع إصدار قديم | سجل التغييرات، والتصحيح المنشور، والاختبارات |
| حزمة أعاد بناءها طرف ثالث | إعادة بناء من مصادر شخص آخر، بتعديل أو دونه | المصادر، والتصحيحات، والتوقيع، وقابلية إعادة الإنتاج |
| حزمة تبنيها مؤسستك وتوقّعها | خط إنتاج داخلي (الجزء 5) | كل شيء من حيث المبدأ: وعليك تحمّل الكلفة |
دراسة حالة: مستودع Rocketsky
لنفحص بموضوعية الفروع المعروضة على yum.rocketsky.ch. إنه مصدر من طرف ثالث وغير رسمي، أقيّمه دون افتراض أنه موثوق أو خطير.
ما تذكره الصفحة (اطّلعتُ عليها في 25 أكتوبر 2026): حزم RPM موقَّعة لـ CentOS 7 على معمارية x86_64، وتسعة فروع موسومة «Available» (5.6.40 و7.1.33 و7.4.33 و8.0.30 و8.1.34 و8.2.35 و8.3.36 و8.4.27 و8.5.12)، مبنية على تجميع Remi لـ EL7، مع gpgcheck=1 وrepo_gpgcheck=1 وsslverify=1، وبصمة مفتاح منشورة، وحزم RPM مصدرية، و«سجلات المنشأ» (provenance records)، وفهرس للحزم مع بصماتها، وإضافة تمنع تغيير الفرع بالخطأ. وتصف صفحة KNOWN-LIMITATIONS-7.4 النسخة 20261021.1.el7.rocketsky: يبقى الرقم الفرعي 7.4.33، ويؤدي التصحيح المعتمد إلى إنهاء العملية فوراً عند نفاد الذاكرة (دون تنفيذ دوال الإنهاء) وتعطيل تتبّع تقدم رفع الجلسة. وتوثّق الصفحة أيضاً عيوباً سابقة (GD وICU وسطر الأوامر التفاعلي).
ما يمكن التحقق منه، ولذلك يجب التحقق منه: بصمة المفتاح عبر قناة غير الموقع نفسه (والموقع يوصي بذلك)، وحزم RPM المصدرية وفرق التصحيح مقارنة بالشيفرة الرسمية، والمحتوى الدقيق لكل حزمة مقارنة بالحزمة التي تستخدمها أصلاً.
ما لم أستطع إثباته:
- في الصفحات التي راجعتها لم أجد هوية ناشر أو مؤسسة يمكن تحديدها؛ ويشير الموقع إلى تمويل بالتبرعات (رابط Ko-fi). وهذا لا يقول شيئاً عن جودة العمل، لكنه يؤثر في قرار مؤسسي (الاستمرارية والمسؤولية والدعم).
- بالنسبة للفرعين 5.6 و7.1، لم تنشر PHP أي تصحيح بالمصدر: فالتصحيح إذن تكييف من طرف ثالث، ولا أستطيع تأكيد مطابقته.
- يوفّر المستودع المشترك
rocketsky-php-commonتبعيات للتشغيل؛ وتضم قائمة حزم RPM المصدرية فيه مكوّنات نظام (مثل httpd وglibc). ولم أحدد إن كان بإمكانها استبدال حزم نظام مثبّتة. تحقق قبل تفعيل ذلك المستودع، مثلاً بتفعيل مستودع الفرع المطلوب وحده بالخيارين--disablerepo='*' --enablerepo=...وفحص المعاملة قبل تنفيذها. - لا تقييم لأمن بقية سلسلة البناء (جهاز البناء، وحماية المفتاح).
تقديري: لا توصية ولا تحذير. قد يكون مستودع الطرف الثالث جسراً معقولاً، شرط أن تعامله كتبعية حرجة: تحقق، واختبر، وخطّط للخروج منه.
فحوص قبل استخدام مستودع من طرف ثالث
- هوية المسؤول عن الصيانة وسمعته: من هو، وما هيكله، ومنذ متى، وما سجل الإشعارات التي نشرها.
- تتبّع المصادر والتصحيحات: مصادر أصلية محددة، وتصحيحات منشورة وقابلة للمراجعة.
- المطابقة للتصحيح المنتظر: قارن الفرق (diff) بالتصحيح الرسمي للفرع المصدر (مثل فروع PHP-7.4/8.0/8.1)؛ وإن كان التصحيح صيغة مختلفة (كإنهاء فوري بدل إنهاء ناعم) فافهم فروق السلوك.
- قابلية إعادة الإنتاج: هل يمكنك إعادة بناء حزمة RPM من حزمة المصدر والحصول على نتيجة مماثلة؟
- التوقيع وإدارة المفاتيح: بصمة مُتحقَّق منها خارج القناة نفسها، و
gpgcheckوrepo_gpgcheckمفعّلان، وخطة لتدوير المفتاح أو لحالة اختراقه. - التوافق: واجهة التطبيقات الثنائية (ABI)، والإضافات (PECL والداخلية)، ومكتبات النظام، والإعداد القائم.
- اختبارات الانحدار والتراجع: بيئة اختبار مطابقة للإنتاج، والاحتفاظ بالحزمة السابقة، وإجراء تراجع مجرَّب.
رقم الإصدار لا يثبت شيئاً
قد تحتفظ حزمة «مصحَّحة» بالرقم نفسه (7.4.33): فيتغير فقط release الحزمة. وبالعكس، قد يخفي رقم متطابق حزمة غير مصحَّحة. تحقق إذن تقنياً: سجل تغييرات يذكر الثغرة، ومقارنة بالتصحيح المرجعي، واختبار سلوك في مختبر. وانتبه: يجب أن يطابق الاختبارُ التصحيحَ. فقتل العملية الفوري والتوقف «الناعم» في التصحيح الرسمي لا يتصرفان بالطريقة نفسها، وقد لا يصلح اختبار صالح لأحدهما للآخر.
الجزء 5: بناء مستودع حزم آمن خاص بك
بالنسبة لناشري البرمجيات والإدارات العامة والمؤسسات التي يجب أن تتحكم في مصدر حزمها، ليس المستودع الداخلي ترفاً. ولنميّز بين ثلاثة أمور كثيراً ما تُخلط:
- المرآة تنسخ حزم طرف ثالث دون تغيير. تحسّن التوافر، لا الثقة.
- مستودع يعيد توزيع حزم الأطراف الثالثة ينشرها مجدداً بعد فحص السلامة. تكسب التحكم في الوصول والتوقيت، لكن المحتوى يبقى محتوى الطرف الثالث.
- خط إنتاج داخلي لإعادة البناء والتحقق ينطلق من مصادر مُتحقَّق منها، ويطبّق تصحيحات مراجَعة، ويبني ويختبر ويوقّع بمفتاحك. وهو الخيار الوحيد الذي يمنحك تحكماً من البداية إلى النهاية.
- جلب مصدر محدد الهوية. أرشيف رسمي أو فرع علني للمشروع، مع تدوين الإصدار بدقة.
- التحقق من السلامة والمصدر. توقيع الإصدار، وبصمة تُقارَن عبر قناة ثانية.
- تطبيق تصحيح قابل للتتبّع. التصحيح الرسمي حيث وُجد (للفروع 7.4 و8.0 و8.1، فروع مشروع PHP)، بعد مراجعته وإدخاله في نظام الإصدارات.
- البناء في بيئة خاضعة للتحكم. جهاز أو حاوية بناء نظيفة، وتبعيات مثبّتة، وسجل محفوظ.
- الاختبار. وظيفي (تطبيقاتك)، وأمني (السلوك أمام الطلبات المفخَّخة، في مختبر)، وانحدار (الرفع، والإضافات).
- توقيع الحزم. مفتاح مخصص، يُحفظ في مكان آمن (وحدة عتادية أو خزنة)، مع إجراء تدوير.
- النشر في مستودع موثَّق الوصول. وصول مقيّد، وبيانات وصفية موقَّعة.
- النشر التدريجي. بضعة أجهزة أولاً، ومراقبة، وإصدار سابق جاهز.
هذا النهج استراتيجية لإدارة المخاطر وليس ضماناً. وله كلفة حقيقية: على أحدهم متابعة الإشعارات الأمنية لـ PHP وللمكتبات المرتبطة بها (OpenSSL وlibxml2 وGD...)، وإعادة البناء بانتظام، وتجديد النسخ المبنية، والحفاظ على الكفاءة. والفرع الذي يتخلى عنه مسؤولوه يصبح مسؤوليتك: كل ثغرة جديدة عليك نقل إصلاحها. وبعد تجميد الفرع القديم، يبقى الهدف الحقيقي هو مغادرته.
الجزء 6: إضافة دفاع مكمّل باستخدام ModSecurity
جدار حماية تطبيقات الويب (WAF) يفحص طلبات HTTP قبل وصولها إلى التطبيق. وModSecurity محرك ترشيح مفتوح المصدر؛ يُثبَّت وحدةً في Apache، أو أمام nginx عبر موصّل. ويطبّق قواعد، غالباً ضمن مجموعات مثل OWASP Core Rule Set (CRS) التي تكشف عائلات هجمات عامة (حقن SQL وXSS...).
الكشف والحجب والإصلاح ثلاثة أمور مختلفة. الكشف يطلق إشارة؛ و*الحجب* يمنع مرور الطلب؛ و*الإصلاح* يزيل العيب. وتحديث PHP وحده يصلح.
وبالنسبة إلى PHP2Shell، توصي المصادر الرسمية بالتدخل أيضاً في الواجهة الأمامية: تقييد حجم الطلب بعد فك ترميزه (حتى دون Content-Length)، وعدد الحقول وأجزاء multipart والترويسات وعمق التداخل، أو حجب multipart إن لم يحتجه التطبيق (إشعار GHSA). وتوجد أيضاً قواعد مجتمعية (مثل هذا المستودع أو هذا التحليل): وهي مصادر من أطراف ثالثة لم أدققها، ولم أجد مجموعة قواعد رسمية من OWASP CRS مخصصة لهاتين الثغرتين.
حدود جدار الحماية: يحلل الجدار جسم multipart على طريقته، وقد يختلف عن PHP (فروق في التحليل، وترميزات، وطلبات مجزّأة)؛ وتتجاوز متغيرات الهجوم التواقيع الضيقة؛ وتتسبب القواعد الصارمة في إيجابيات كاذبة (مثل نماذج مشروعة ذات حقول متداخلة)؛ وكل مسار يتجاوز الجدار (وصول مباشر إلى الخادم الأصلي، أو منفذ آخر، أو خدمة داخلية) يبقى مكشوفاً.
مثال يُختبر في بيئة خاضعة للتحكم
الموجّهات والمتغيرات أدناه موجودة في دليل مرجع ModSecurity v2 (ARGS_NAMES وFILES_NAMES والمعاملان @streq و@rx). أنا لم أشغّل هذه القواعد: فالصياغة تتبع التوثيق، لكن سلوكها على بنيتك يبقى بحاجة إلى تحقق. وهي ليست حماية شاملة.
# Observation only: nothing is blocked
SecRuleEngine DetectionOnly
SecRequestBodyAccess On
SecAuditEngine RelevantOnly
# Session upload progress tracking field (see CVE-2026-109619)
SecRule ARGS_NAMES "@streq PHP_SESSION_UPLOAD_PROGRESS" \
"id:9900001,phase:2,pass,log,auditlog,msg:'Session upload progress field'"
# Field names nested three levels or more (may hit legitimate forms)
SecRule FILES_NAMES|ARGS_NAMES "@rx \[[^\]]*\]\[[^\]]*\]\[[^\]]*\]" \
"id:9900002,phase:2,pass,log,auditlog,msg:'Deeply nested field name'"
المعرّفان 9900001 و9900002 اعتباطيان: كيّفهما مع نطاقك المحلي.
منهج تشغيلي
- جرد نقاط الدخول: كل سكربتات PHP التي يمكن الوصول إليها، والمضيفات الافتراضية، والمنافذ، والمسارات المباشرة إلى الخادم الأصلي، والوصول الداخلي.
- التفعيل والضبط: محرك القواعد، والوصول إلى جسم الطلب، وحدود الحجم، وسجل التدقيق.
- المراقبة في وضع الكشف (
DetectionOnly) خلال فترة ممثِّلة. - تحليل السجلات: أي الطلبات المشروعة يُبلَّغ عنها، ومن أين تأتي الأخرى.
- الضبط: استثناءات موجّهة، وعتبات، ومستوى الارتياب (paranoia level) في CRS.
- الانتقال إلى الحجب بعد معالجة الإيجابيات الكاذبة، في نطاق محدود أولاً.
- اختبار الانحدار: النماذج، والرفع، والواجهات البرمجية.
- المراقبة المستمرة: تنبيهات، ومراجعة دورية للقواعد. فجدار حماية لا يُراجَع أبداً يصبح شعوراً زائفاً بالأمان.
الجدار يكمّل المعالجة، ولا يحلّ محلها.
الجزء 7: خطة عمل مرتبة بحسب الأولوية
خلال 24 ساعة
- جرد خوادم PHP المكشوفة على الإنترنت، ونمطها (mod_php أو FPM)، ومصدرها، وإصدارها الفعلي.
- تطبيق الإجراءات المؤقتة والجزئية من الإشعار الرسمي، مع فهم آثارها: فرض
memory_limit=-1بحيث لا تستطيع التطبيقات تغييره (مثلاًphp_admin_valueفي مجمّع FPM)، وpost_max_sizeمنخفضة (8M، أو 32M إن لزم رفع الملفات)، وsession.upload_progress.enabled=0فيphp.iniأو إعداد المجمّع (لا عبرini_set()ولا.user.ini)، وإعادة تشغيل كل العاملين. إنmemory_limit=-1يزيل سقف الذاكرة ويزيد خطر النفاد: فخطّط لحد على مستوى الحاوية أو cgroup، لكن ليسRLIMIT_ASولاRLIMIT_DATA، اللذين ينصح الإشعار بتجنبهما لأنهما قد يتسببان في فشل الحجز المقصود نفسه. وفي PHP 8.5، يحجبfatal_error_backtraces=0المسار المعروف عبر تتبعات الأخطاء القاتلة. - تطبيق حدود في الواجهة الأمامية (الحجم بعد فك الترميز، وعدد الأجزاء).
خلال الأسبوع
- التحديث إلى تصحيح مؤكد: 8.2.35 أو 8.3.36 أو 8.4.27 أو 8.5.12، أو حزمة توزيعة مصحَّحة.
- بالنسبة للفروع القديمة: الاختيار بين مورّد LTS، ومستودع طرف ثالث جرى تقييمه (الجزء 4)، وإعادة بناء داخلية (الجزء 5).
- وضع ضوابط معوِّضة: جدار حماية في وضع الكشف، ثم الحجب.
- البحث عن علامات اختراق: ملفات PHP حديثة غير متوقعة، وعمليات أبناء غير طبيعية لخدمة الويب، وطلبات
multipartمشبوهة في السجلات.
خلال الشهر
- التحقق (اختبارات انحدار)، والمراقبة، وتوثيق إجراء التراجع.
- البت في إنشاء مستودع داخلي ومن يصونه.
- التخطيط للتحديث: تاريخ خروج لكل فرع انتهى عمره.
نقطة ثالثة تستحق المتابعة: في 23 أكتوبر نشرت PHP إشعاراً إعلامياً عن ثغرة ثالثة، CVE-2026-115560، مرتبطة بميزة تتبّع تقدم رفع الجلسة نفسها؛ وبحسب Red Hat فإن تعطيل هذه الميزة يعالجها بالكامل. ولم أحلل ذلك الإشعار بالتفصيل.
ملخص الخيارات
| الخيار | الملاءمة | القيود | الحدود |
|---|---|---|---|
| PHP من 8.2 إلى 8.5 مصحَّحة | الحالة العامة | توافق التطبيق، والترحيل | رقم فرع حديث لا يكفي، بل يلزم الإصدار الصحيح |
| حزمة توزيعة مصحَّحة | Debian وRHEL ومشتقاتهما المدعومة | دورة حياة التوزيعة | إصدار مجمّد، وتحقق من سجل الحزمة |
| مورّد LTS مدفوع | فروع انتهى عمرها، وحاجة إلى دعم | الكلفة، والاعتماد التعاقدي | جودة وآجال خاصة بكل مورّد |
| مستودع طرف ثالث جرى تقييمه (مثل Rocketsky) | جسر مؤقت على CentOS 7 | التحقق من المفتاح والتصحيحات وABI | هوية المسؤول غير مثبتة، ومصدر غير رسمي للتصحيح في 5.6 و7.1 |
| البناء من فروع المشروع | 7.4 و8.0 و8.1 مع كفاءة داخلية | خط الإنتاج، والاختبارات | مسؤولية كل تصحيح مستقبلي |
| مستودع وخط إنتاج داخليان | الناشرون، والإدارات | كلفة الصيانة، وإدارة المفاتيح | ليس ضماناً؛ وتجديد مستمر |
| إعدادات PHP وحدود في الواجهة الأمامية | الطوارئ | آثار جانبية (الذاكرة، ورفع الملفات) | جزئي: لا يزيل العيب |
| جدار حماية (ModSecurity) | دفاع متعدد الطبقات | الضبط، والإيجابيات الكاذبة | يمكن تجاوزه، ولا يحل محل التصحيح |
المصادر والمراجع
مصادر أولية (مشروع PHP والمورّدون):
- PHP، إعلان 21 أكتوبر 2026: إشعار أمني حرج، والإصدارات المصحَّحة، وفروع التصحيح الأدنى، والإجراءات المؤقتة.
- PHP، إشعارا GitHub GHSA-w8hw-w9fx-j79w (CVE-2026-109618) وGHSA-6wmf-4rv5-p3rp (CVE-2026-109619)، المرتبطان بإعلان 21 أكتوبر 2026.
- PHP، الفروع المصدرية 7.4 و8.0 و8.1.
- Red Hat، RHSB-2026-013، نُشرت في 21 أكتوبر 2026 وحُدّثت في 23 أكتوبر 2026.
- Debian، السجل الأمني لـ CVE-2026-109618، اطُّلع عليه في 25 أكتوبر 2026.
- معرّفات CVE: CVE-2026-109618 وCVE-2026-109619.
- ModSecurity، دليل المرجع v2، المتغيرات والمعاملات؛ وOWASP Core Rule Set.
مصادر من أطراف ثالثة أو غير رسمية:
- Calif، PHP2Shell: A tale of two PHP remote vulnerabilities: المكتشفون، والسرد التقني، والتسلسل الزمني (صفحة بلا تاريخ نشر ظاهر، اطُّلع عليها في 25 أكتوبر 2026).
- Sansec، PHP2Shell: PHP RCE: تحليل المخاطر وجدول بمقدّمي التصحيحات للفروع القديمة (التاريخ غير مسجَّل).
- Rocketsky، PHP for CentOS 7 وحدود الفرع 7.4: مستودع طرف ثالث جرى تقييمه، اطُّلع عليه في 25 أكتوبر 2026.
- Assetnote،
php2shell-scanner(مستودع علني): قرأتُ الشيفرة وملف README محلياً. - قواعد ModSecurity المجتمعية: eness وjaiswalakshansh، لم تُدقَّق.
نقاط لم أتحقق منها: درجة CVSS (مأخوذة من مصادر ثانوية)، وحالة دعم Debian 11 (ELTS)، وتصحيحات Remi وSury (وردت عند Sansec)، وحالة صور Docker الرسمية للإصدار 8.1 وما قبله (Sansec)، ومطابقة تصحيحات الأطراف الثالثة لتصحيحات المشروع، وأي تطور بعد 25 أكتوبر 2026.