WorldwideTradeX یک شرکت بازرگانی مستقر در استانبول است: تأمین می‌کنیم، صادر می‌کنیم و تحویل می‌دهیم.

راهکارهای فناوری اطلاعات · اطلاعیه امنیتی

به‌روزرسانی امنیتی PHP در ۲۰۲۶: راهنمای رفع آسیب‌پذیری PHP2Shell با شدت CVSS 9.2

در ۲۱ اکتبر ۲۰۲۶ تیم PHP نسخه‌های 8.5.12، 8.4.27، 8.3.36 و 8.2.35 را برای رفع دو آسیب‌پذیری اجرای کد از راه دورِ بدون نیاز به احراز هویت منتشر کرد. اگر سرور شما، سرور مشتری‌تان یا هاست اشتراکی آژانس‌تان با PHP کار می‌کند، این موردی است که باید امروز ارتقا یابد، نه آیتمی برای نقشهٔ راه.

۲۱ اکتبر ۲۰۲۶  ·  ۱۱ دقیقه مطالعه  ·  میز فناوری WorldwideTradeX
پاسخ کوتاه. دو اشکال در خودِ PHP — با شناسه‌های CVE-2026-109618 و CVE-2026-109619 که به‌طور گسترده با نام PHP2Shell شناخته می‌شوند — به یک درخواست بدون احراز هویت اجازه می‌دهند روی سرور کد اجرا کند. شدت هر دو CVSS v4.0 9.2 ارزیابی شده است. نسخه‌های اصلاح‌شده: PHP 8.5.12, 8.4.27, 8.3.36, 8.2.35. هر PHP‌ای که ترافیک وب سرو می‌دهد در دامنهٔ خطر قرار می‌گیرد — PHP-FPM، Apache با mod_php، php-cgi، LiteSpeed و FrankenPHP — و بیشترین ریسک متوجه mod_php است. ارتقا تنها راه‌حل کامل است؛ تنظیمات موقتی که در اطلاعیه آمده فقط پنجرهٔ ریسک را تنگ‌تر می‌کنند. ما سرورهای production مبتنی بر PHP را اداره و مهاجرت می‌دهیم؛ اگر می‌خواهید مالکیت پنجرهٔ ارتقا را کس دیگری بر عهده بگیرد، درخواست پیش‌فاکتور بدهید یا با ما تماس بگیرید.

فرایند افشای این آسیب‌پذیری خودش غیرمعمول بود. در ۲۰ اکتبر، تیم امنیتی PHP یک اطلاعیهٔ پیشاپیش منتشر کرد، انتشار نسخه‌های جدید را برای ۲۱ اکتبر ساعت ۱۴:۰۰ UTC تعیین کرد و این حق را برای خود نگه داشت که در صورت لزوم زودتر هم منتشر کند. شناسه‌های CVE یک روز پیش از افشای رسمی درز کردند، همراه با ادعاهای اغراق‌آمیزی درباره شدت و نسخه‌های متأثر. سازندگان توزیع‌ها وصله‌های مربوط به توزیع‌های خود را از قبل دریافت کرده بودند و مراکز CERT ملی حتی پیش از عمومی‌شدن کد، راهنمایی‌های خود را منتشر کردند. به عبارت دیگر: به محض انتشار نسخهٔ اصلاح‌شده، هیچ‌کس بهانهٔ مشروعی برای تأخیر نداشت.

دو آسیب‌پذیری، یک انتشار اضطراری

هیچ‌کدام از این دو اشکال، خطای منطقی در یک برنامه نیستند. هر دو در نحوهٔ آماده‌سازی و جمع‌کردن درخواست توسط PHP قرار دارند و به همین دلیل هیچ به‌روزرسانی فریم‌ورک، به‌روزرسانی افزونه یا قانون WAF جایگزین ارتقای مفسر نمی‌شود.

CVE-2026-109618 — اجرای کد از راه دور از طریق خرابی ناشی از اتمام حافظه. وقتی حافظهٔ PHP تمام می‌شود، به‌جای ادامهٔ کار، درخواست را ساقط می‌کند. اطلاعیه مسیری را توصیف می‌کند که در آن این ساقط‌شدن، PHP را در حالی متوقف می‌کند که داده‌های داخلی درخواست فقط تا حدی مقداردهی اولیه شده‌اند؛ در نتیجه مرحلهٔ پاک‌سازی درخواست بعدها داده‌های نامعتبر را معتبر فرض می‌کند. مهاجمی که بتواند مصرف حافظه را به سقف برساند، می‌تواند ادامهٔ رویدادها را جهت دهد. همین اشکال است که توصیه‌های کاهش ریسک را این‌قدر خلاف شهود می‌کند: سازنده از مدیران سیستم می‌خواهد مانع رسیدن PHP به سقف حافظهٔ خودش شوند، نه اینکه آن سقف را تنگ‌تر کنند.

CVE-2026-109619 — اجرای کد از راه دور از طریق وضعیت سراسریِ به‌جامانده. وضعیت داخلی متعلق به یک درخواست می‌تواند پس از آزادشدن حافظهٔ پشت آن زنده بماند. درخواست بعدی‌ای که همان فرایند ورکر پردازش می‌کند، ممکن است پیش از آنکه مقداردهی اولیهٔ معمول آن را بازنشانی کند، از این وضعیت کهنه استفاده کند. روی ورکری طولانی‌عمر — که دقیقاً همان چیزی است که PHP-FPM، mod_php و LiteSpeed هستند — بازاستفاده از حافظه وضعیتی عادی و همیشگی است؛ به همین دلیل این مورد یک استثنای نادر برای پیکربندی‌های خاص نیست.

شناسه شرح شدت اصلاح شده در
CVE-2026-109618
GHSA-w8hw-w9fx-j79w
مدیریت اتمام حافظه، PHP را با داده‌های درخواستِ تنها تا حدی مقداردهی‌شده متوقف می‌کند؛ مرحلهٔ پاک‌سازی بعداً به داده‌های نامعتبر اعتماد می‌کند CVSS v4.0 9.2 8.5.12 · 8.4.27 · 8.3.36 · 8.2.35
CVE-2026-109619
GHSA-6wmf-4rv5-p3rp
وضعیت متعلق به یک درخواست پس از آزادشدن حافظه‌اش باقی می‌ماند؛ درخواستی بعدی روی همان ورکر پیش از مقداردهی مجدد از آن استفاده می‌کند CVSS v4.0 9.2 8.5.12 · 8.4.27 · 8.3.36 · 8.2.35

نام PHP2Shell برچسب رسمی پروژهٔ PHP نیست؛ پژوهشگران و شرکت‌های امنیتی آن را به کار بردند و نام ماندگار شد، پس آن را در خروجی اسکنرها، بولتن‌های هاستینگ و اطلاعیه‌های CERT خواهید دید که دقیقاً به همین دو CVE اشاره می‌کنند.

چه کسانی واقعاً در معرض خطر هستند

اطلاعیه صراحت دارد: تمام نصب‌های PHP که به درخواست‌های وب پاسخ می‌دهند در معرض ریسک‌اند. این شامل PHP-FPM پشت nginx یا Apache، Apache با mod_php، php-cgi، LiteSpeed و FrankenPHP می‌شود. تفاوت این پیکربندی‌ها فقط در مقدار کاری است که یک مهاجم باید انجام دهد.

پیکربندی ریسک دلیل
Apache با mod_php بیشترین اطلاعیه اکسپلویتی به‌اثبات‌رسیده را توصیف می‌کند که در آن یک درخواست بدون احراز هویت، حمله را پیش از اجرای هر کد برنامه‌ای فعال می‌کند
PHP-FPM (nginx، پروکسی Apache) زیاد ورکرهای طولانی‌عمر وضعیت درخواست را بازاستفاده می‌کنند؛ ورکر معمولاً با همان کاربری اجرا می‌شود که سایت با آن کار می‌کند
LiteSpeed, php-cgi, FrankenPHP زیاد در اطلاعیه به‌عنوان پیکربندی‌های سرو‌دهندهٔ درخواستِ در دامنهٔ خطر نام برده شده‌اند
هاستینگ مدیریت‌شده و اشتراکی متفاوت است — بپرسید معمولاً در لایهٔ پلتفرم وصله می‌شوند، اما شما دیدی به آن ندارید؛ کار شما این است که نسخهٔ built-in و تاریخ وصله‌شدن را کتباً دریافت کنید
کارهای cron و اسکریپت‌های CLI کمتر، اما همچنان به‌روزرسانی کنید سطح درخواست عمومی ندارند، اما از همان باینری مشترک استفاده می‌کنند و اغلب حاوی اعتبارنامه‌ها هستند

اگر برای کسب‌وکار تجاری‌تان WordPress، WooCommerce، Laravel، Magento، سامانه‌های ERP هم‌خانوادهٔ Magento یا هر پرتال رزرو مبتنی بر PHP را میزبانی می‌کنید، حتی وقتی کد برنامه بی‌نقص است، در یکی از سه سطر اول این جدول قرار می‌گیرید. برای نگاهی گسترده‌تر به اینکه از اساس چه کسی باید مالک runtime باشد، راهنمای ما دربارهٔ برون‌سپاری IT در ترکیه را بخوانید.

نسخهٔ خود را در دو دقیقه بررسی کنید

دام اینجا حساب‌وکتاب نسخه‌هاست. توزیع‌ها سال‌ها PHP 8.3.6 یا 8.2.x را ارائه می‌کنند و اصلاحات امنیتی را به همان شمارهٔ نسخهٔ قابل‌مشاهده باک‌پورت می‌کنند، پس php -v به‌تنهایی نمی‌گوید محافظت می‌شوید یا نه. سه چیز را مقایسه کنید.

۱. نسخهٔ قابل‌مشاهدهٔ PHP و SAPI‌ای که ترافیک را سرو می‌دهد.

php -v
php -i | grep -E 'PHP Version|memory_limit|session.upload_progress.enabled|fatal_error_backtraces'
systemctl list-units --type=service --state=running | grep -Ei 'php|apache|nginx|litespeed'

۲. نسخهٔ بستهٔ توزیع، نه نسخهٔ upstream. در Debian و Ubuntu گزارش تغییرات پاسخ صادقانه است؛ در سیستم‌های RPM از گزارش تغییرات بسته جست‌وجو کنید.

dpkg -l | grep -E 'php8\.[0-9]-(fpm|cli)|libapache2-mod-php'
zcat /usr/share/doc/php8.3-cli/changelog.Debian.gz | grep -iE 'CVE-2026-10961[89]'
apt-cache policy php8.3-fpm | head -4
# RPM-based hosts
rpm -q php && rpm -q --changelog php | grep -iE 'CVE-2026-10961[89]'

اگر گزارش تغییرات در نسخهٔ نصب‌شده به هر دو CVE اشاره کرده باشد، وصله شده‌اید، حتی اگر php -v هنوز 8.3.6 را نشان دهد. این همان تفاوت یک پاسخ امنیتی واقعی با یک خرافهٔ شماره‌نسخه است.

۳. آیا فرایند در حال اجرا باینری وصله‌شده را بارگذاری مجدد کرده است. به‌روزرسانی بسته‌ای که هرگز به ری‌استارت منجر نشود، کد قدیمی را در حافظه نگه می‌دارد. زمان شروع سرویس را با زمان نصب بسته مقایسه کنید:

systemctl show php8.3-fpm -p ActiveEnterTimestamp -p MainPID
stat -c '%y %n' /usr/sbin/php-fpm8.3

در cPanel، Plesk، DirectAdmin یا یک پلتفرم مدیریت‌شده، معادل همین کار انتخابگر PHP به‌علاوهٔ بولتن امنیتی خود هاست است: نسخهٔ built-in‌ای که سایت‌تان واقعاً به آن تخصیص یافته را مشخص کنید، نه جدیدترین نسخه‌ای که در پنل تبلیغ می‌شود. اگر هاست شما نمی‌تواند تاریخ وصله‌شدن را بگوید، سایت را وصله‌نشده تلقی کنید. خدمات زیرساخت دیجیتال ما همین بازرسی به‌همراه خودِ ارتقا را پوشش می‌دهد؛ همچنین می‌توانید به‌سادگی استک خود را بنویسید و با ما تماس بگیرید تا بگوییم در جای شما چه چیزهایی را بررسی می‌کردیم.

نسخه‌های اصلاح‌شده و پرتگاه پایان پشتیبانی

PHP هر شاخه را دو سال توسعهٔ فعال و دو سال دیگر اصلاحات امنیتی پشتیبانی می‌کند. همین سیاست بود که در ۲۱ اکتبر به چهار اصلاح هم‌زمان انجامید — و همین سیاست شاخه‌های قدیمی‌تر را نیز رها می‌کند.

شاخه نسخهٔ اصلاح‌شده وضعیت پس از این اطلاعیه
PHP 8.5 8.5.12 پشتیبانی فعال
PHP 8.4 8.4.27 پشتیبانی فعال
PHP 8.3 8.3.36 مرحلهٔ پشتیبانی امنیتی
PHP 8.2 8.2.35 پشتیبانی امنیتی در ۳۱ دسامبر ۲۰۲۶ پایان می‌یابد — همین حالا برای جهش برنامه‌ریزی کنید
PHP 8.1 و قدیمی‌تر نسخهٔ upstream منتشر نشده فقط باک‌پورت‌های سازنده؛ پروژهٔ PHP برای کسانی که از سورس بیلد می‌گیرند، باک‌پورت‌های سورس حداقلی برای 7.4، 8.0 و 8.1 منتشر کرده است

دو هشدار کاربردی از طرف اطلاعیه. نخست، اگر PHP را از یک مخزن اجتماعی نصب می‌کنید نه از توزیع خودتان، آن مخزن ممکن است از پنجرهٔ امنیتی عقب بماند: نگهدارندگان بسته‌های پرکاربرد Remi اعلام کردند که به‌روزرسانی هم‌روز نخواهند داشت، پس مسیر امن بسته‌های توزیع خودتان یا بیلد از سورس است. دوم، اگر روی PHP 8.1 یا قدیمی‌تر هستید، «منتظر هاستمان می‌مانیم» تصمیمی امنیتی است که به نمایندگی از مشتریان‌تان می‌گیرید — آن را مستند کنید یا تغییرش دهید.

وصله‌کردن سرور Production بدون بروز حادثه

به‌روزرسانی‌های امنیتی هم‌نسخه به‌ندرت برنامه‌ای را می‌شکنند؛ آنچه می‌شکند ری‌استارت‌های آزموده‌نشده است. ترتیب زیر همان چیزی است که ما در پلتفرم‌های تجاری زنده به کار می‌بندیم و پنجرهٔ ریسک را کوتاه نگه می‌دارد، بدون اینکه سایت را به قمار بگذاریم.

  1. اول اسنپ‌شات. یک اسنپ‌شات hypervisor یا volume که بازیابی‌اش را واقعاً آزموده‌اید در چند دقیقه برمی‌گردد و تصمیم به وصله‌کردن را ارزان می‌کند.
  2. نسخه را در استیجینگ بازسازی کنید. همان شاخه، همان افزونه‌ها، همان فایل‌های پیکربندی PHP و یک کپی از داده‌های production. مسیرهای تسویه‌حساب، درخواست پیش‌فاکتور و پرداخت را اجرا کنید، نه فقط صفحهٔ اصلی را.
  3. مجموعهٔ بسته‌ها را یکجا ارتقا دهید. ترکیب CLI ارتقایافته با باینری قدیمی FPM همان راهی است که برخی با php -v وصله‌شده اما مسیر وب وصله‌نشده تمام می‌کنند: apt-get update && apt-get install --only-upgrade 'php8.3-*'، یا روی هاست‌های RPM dnf update --security 'php*'.
  4. فرایند سرو‌دهندهٔ درخواست را ری‌استارت کنید، سپس از ری‌استارت‌شدنش مطمئن شوید. systemctl restart php8.3-fpm (یا reload کردن Apache / ری‌استارت LiteSpeed)، بعد زمان شروع سرویس را دوباره بررسی کنید و پرس‌وجوهای نسخه و گزارش تغییرات را یک بار دیگر اجرا کنید.
  5. یک ساعت گزارش خطا را زیر نظر بگیرید. پیام‌های OOM، امضاهای جدید خطاهای مهلک و نرخ‌های غیرعادی 5xx سیگنال‌هایی هستند که ممکن است نشان دهند تنظیمات کاهش ریسکِ در ادامه نیاز به تنظیم مجدد دارند — نه دلیلی برای به تعویق انداختن ارتقا.
  6. مدرک را ثبت کنید. نسخهٔ بسته، سطر گزارش تغییرات که به هر دو CVE اشاره می‌کند و زمان ری‌استارت. مشتری‌ها، حسابرسان و بازبینی‌های کنترلی از جنس ISO 27001 دقیقاً همین‌ها را می‌خواهند و ذخیره‌کردنشان ده ثانیه وقت می‌برد.

جایی که ارتقا باید منتظر بماند — یک یکپارچه‌سازی ERP اعتبارسنجی‌شده، تقویم انتشار با محدودیت زمانی، چرخهٔ تأیید مشتری — همان روز یک کنترل جبرانی جلویش بگذارید، نه اینکه پورت را باز بگذارید و امیدوار بمانید. توصیهٔ اطلاعیه‌های مراکز CERT ملی برای دقیقاً همین موقعیت همین بود: هرجا وصله‌کردن فوری ممکن نیست، برنامه‌های PHP روبه‌اینترنت را از شبکهٔ عمومی جدا کنید.

تدابیر کاهش ریسک موقت: پنجره را تنگ‌تر کنید، کامل نبندید

اطلاعیهٔ PHP بی‌پرده می‌گوید که هیچ تدبیر کاهشی کاملی وجود ندارد و به‌روزرسانی تنها انتخاب امن است. موارد زیر را به‌عنوان پوششی برای چند روز، نه چند هفته، به کار ببرید؛ در سطحی اعمال کنید که برنامه نتواند آن را دور بزند، و پس از آن همهٔ ورکرها را ری‌استارت کنید.

در برابر CVE-2026-109618 (مسیر اتمام حافظه)

  • بگذارید PHP به‌جای سقف خودش به حافظهٔ کل ماشین برسد: memory_limit = -1، و ترجیحاً به شکل php_admin_value memory_limit = -1 تا کد برنامه نتواند سقف را سرِ جایش برگرداند.
  • بدنهٔ درخواست‌ها را در مفسر کوچک نگه دارید: راهنمای اطلاعیه حدود 8 MB برای وقتی است که آپلودی در کار نیست و حدود 32 MB برای وقتی که آپلود وجود دارد، به‌شرط آنکه upload_max_filesize کوچک‌تر از post_max_size باشد.
  • محدودیت‌های پرهزینه را در پروکسی اعمال کنید، چون خرابی در درخواستِ رمزگشایی‌شده است نه در حجم روی سیم: حجم کل بدنهٔ رمزگشایی‌شده، تعداد فیلدهای ورودی، تعداد بخش‌های multipart، تعداد سربرگ‌ها، عمق تودرتویی — و درخواست‌هایی را هم پوشش دهید که بدون Content-Length قابل‌استفاده می‌رسند.
  • شعاع تخریب را با محدودیت حافظهٔ container یا cgroup‌ای مهار کنید که اگر ورکری کشته شود، رخدادی در سطح دسترس‌پذیری باشد نه در سطح کل هاست. جایگزین RLIMIT_AS یا RLIMIT_DATA نکنید: این دو دقیقاً همان شکست تخصیص حافظه‌ای را فعال می‌کنند که در مسیر آسیب‌پذیری قرار دارد.

در برابر CVE-2026-109619 (مسیر وضعیت به‌جامانده)

  • پیشرفت آپلود نشست را با session.upload_progress.enabled = 0 غیرفعال کنید؛ در php.ini، استخر FPM یا پیکربندی سرور تنظیم شود — جایی که پیش از تجزیهٔ درخواست اعمال گردد. سپس همهٔ ورکرها را ری‌استارت کنید، چون FPM وضعیت ماژول‌های ازقبل مقداردهی‌شده را میان درخواست‌ها مشترک می‌کند. ini_set() و .user.ini برای به‌موقع رسیدن دیر هستند.
  • روی PHP 8.5 مقدار fatal_error_backtraces = 0 را تنظیم و ری‌استارت کنید.
  • تنظیمات per-request نامعتبر یا منسوخ را که در نتیجه در مقداردهی اولیهٔ آغازین پیام تشخیصی صادر می‌کنند حذف کنید. پنهان‌کردن پیام با error_reporting، display_errors یا @ آن مسیر کد را حذف نمی‌کند.
  • در هندلرهای آپلود و import، کدهای callback و روتین‌های پاک‌سازی دنبال خطاهای مهلکِ در دسترس مهاجم و timeoutهای طولانی‌مدت بگردید — همان مکان‌هایی که هر دو اشکال در آن‌ها لانه کرده‌اند.

یک CDN یا WAF جلوی origin همچنان به‌درد می‌خورد: محدودسازی نرخ، مسدودکردن الگوهای غیرعادی درخواست و وصله‌کردن مجازی، نویز را کم و اسکن فرصت‌طلبانه را کُند می‌کنند. برای مهاجمی هدفمند این‌ها سرعت‌گیرند، نه کنترلی که بتوانید آن را به‌عنوان رفع آسیب امضا کنید.

امروز از ارائه‌دهندهٔ هاست خود چه بپرسید

اسکریپت‌های پشتیبانی این پرسش را با «ما همیشه وصله‌شده‌ایم» جواب می‌دهند. به‌جایش مدرکی بخواهید که قابل بایگانی باشد:

  • نسخهٔ built-in PHP تخصیص‌یافته به حساب ما، و اینکه بسته‌ای از توزیع است یا بیلد سازنده.
  • تاریخی که اصلاحات CVE-2026-109618 و CVE-2026-109619 به ناوگان شما رسید، همراه با رشتهٔ نسخهٔ بستهٔ داخلی.
  • آیا اصلاح به SAPI‌ای که سایت ما را سرو می‌کند (FPM، LiteSpeed، mod_php) و به هر نود استیجینگ یا بکاپی که ممکن است بازیابی کنیم اعمال شده است یا نه.
  • اگر پلتفرم هنوز وصله نشده است: چه کنترل جبرانی جای خود دارد و تا چه زمانی.
  • سیاست ثابت شما برای شاخه‌های پایان عمر چیست — در ۱ ژانویه ۲۰۲۷، وقتی پشتیبانی امنیتی PHP 8.2 متوقف می‌شود، با سایت من چه می‌شود.

ارائه‌دهنده‌ای که این پنج پرسش را در یک ایمیل پاسخ دهد، ارائه‌دهنده‌ای است که ارزش نگه‌داشتن دارد. ارائه‌دهنده‌ای که با متن تبلیغاتی برمی‌گردد، موضوع یک گفت‌وگوی مهاجرت است؛ همان سخت‌گیری اینجا لازم است که در کارهای ارزیابی شکاف ISO 27001 ما به کار می‌رود، جایی که تحویل‌دادنیِ پروژه مدرک است، نه اطمینان‌دادن.

آیا باید فرض کنید نفوذ رخ داده است؟

خودکار نه — اما به‌جای حدس‌زدن بررسی کنید، به‌خصوص اگر سرور در بازهٔ پیش از وصلهٔ شما در معرض اینترنت عمومی بوده است.

  • دنبال فرایندها، listenerها و مدخل‌های cron بگردید که خودتان نساخته‌اید، و اتصالات خروجی از کاربرِ ورکر PHP را هم بررسی کنید.
  • پوشه‌های قابل‌نوشتن برنامه را با منبع مرجع دیپلوی مقایسه کنید (diff): فایل‌های PHP جدید، پوشه‌های آپلود تغییریافته، پوشه‌های موقتی که به‌طرز غیرمنتظره‌ای قابل‌اجرا شده‌اند.
  • لاگ‌های وب را برای طوفان‌های درخواست در ساعات افشا، بدنه‌های multipart به‌طرز غیرعادی بزرگ یا درخواست‌هایی که 500 برگرداندند همراه با امضاهای OOM در گزارش خطای PHP بکاویید.
  • بررسی کنید که باینری وصله‌شده واقعاً در حال اجراست — مقایسهٔ زمان ری‌استارت در بالا پاسخ همین را می‌دهد.
  • اگر چیزی ناجور به نظر می‌رسد، با آن مثل یک حادثهٔ امنیتی رفتار کنید: دیسک و لاگ‌ها را حفظ کنید، همهٔ اعتبارنامه‌هایی را که برنامه می‌تواند بخواند بچرخانید و از یک ایمیج سالمِ شناخته‌شده بازسازی کنید. نصب مجدد بستهٔ PHP روی هاستی نفوذشده، رفع آسیب نیست.

یک نمونهٔ عملی از زیرساخت خودمان

ما worldwidetradex.com را روی Ubuntu 24.04 LTS با nginx و PHP-FPM اجرا می‌کنیم، پس در ۲۲ اکتبر همین بررسی‌ها را روی خودمان اجرا کردیم. نتایج، نمونهٔ خوبی است از اینکه چرا حساب‌وکتاب نسخه‌ها اهمیت دارد:

php -v عدد PHP 8.3.6 را گزارش کرد — عددی که در مقایسه با نسخه‌های upstreamِ PHP سه ساله، کهنه و نگران‌کننده به نظر می‌رسد.

dpkg -l نسخهٔ 8.3.6-0ubuntu0.24.04.13 را گزارش کرد و گزارش تغییرات Debianِ همراه بسته برای همین نسخه، CVE-2026-109618 و CVE-2026-109619 را با اعمال وصلهٔ سازنده فهرست کرده است. apt-cache policy نشان داد نسخهٔ نصب‌شده با نسخهٔ کاندید برابر است، پس هیچ نسخهٔ جدیدتری در انتظار نصب نبود.

نتیجه: وصله‌شده از طریق باک‌پورت توزیع، سرو‌دهی با PHP-FPM نه mod_php، و سرویس FPM پس از به‌روزرسانی بسته ری‌استارت شده است. همین بررسی، پنج فرمان، و می‌توانیم مدرکش را به مشتری‌ای که می‌پرسد نشان دهیم.

این درس به هر استکی منتقل می‌شود: وضعیت امنیتی شما یعنی نسخهٔ بسته به‌علاوهٔ گزارش تغییرات به‌علاوهٔ ری‌استارت، نه رشتهٔ نسخهٔ تبلیغاتی در پنل هاستینگ.

وصله‌کردن را روتین کنید، نه قهرمانانه

PHP2Shell به‌خاطر عجیب‌بودن در ذهن نمی‌ماند؛ به‌خاطر این می‌ماند که مفسری که بیشتر وب روی آن اجرا می‌شود یک اشکال بحرانیِ پیش از احراز هویت داشت و هزاران هاست باید ظرف چند ساعت واکنش نشان می‌دادند. تیم‌هایی که در این ماجرا خوابی آسوده داشتند، شانسی در کار نبود — اتوماسیون داشتند.

  • ارتقاهای امنیتی خودکار و بی‌نیاز از دخالت انسان برای مفسر، با ثبت خودکار نسخه و ری‌استارت.
  • یک فهرست دارایی که بداند هر سایت از کدام SAPI و کدام شاخهٔ PHP استفاده می‌کند، شامل استیجینگ، بکاپ‌ها و همان یک WordPressِ مانده از ۲۰۱۹.
  • یک مسیر بازیابی تمرین‌شده، تا «همین حالا وصله کنید» هرگز در برابر «نمی‌توانیم به عقب برگردیم» روی ترازو نرود.
  • یک برنامهٔ شاخه‌ها: هیچ چیزی روی نسخهٔ PHP‌ای نباشد که پشتیبانی امنیتی‌اش طی دوازده ماه آینده تمام می‌شود.
  • برای هر سرور یک مسئول مشخص و نام‌برده، و یک مسیر تشدید و ارجاع کتبی برای روزهایی که وصله ساعت ۱۴:۰۰ UTC یک چهارشنبه فرود می‌آید.

اگر ترجیح می‌دهید این توانایی را بخرید تا اینکه برایش نیرو استخدام کنید، ما به‌عنوان بخشی از کارهای زیرساخت مدیریت‌شدهٔ خود، مالکیت پلتفرم‌های production مبتنی بر PHP را بر عهده می‌گیریم — ریتم وصله‌کردن، پایش، بکاپ‌ها و بازیابی‌های مستند. با یک شرح کوتاه و مقادیر موردنیاز شروع کنید: درخواست پیش‌فاکتور بدهید.

پرسش‌های متداول

اگر وب‌سایتم روی نسخهٔ وصله‌نشدهٔ PHP اجرا می‌شود، قطعاً هک شده است؟

نه، لزوماً نه. یک نصب PHP وصله‌نشده و روبه‌اینترنت در معرض خطر است و اسکن‌ها هم حدود زمان افشا آغاز شد، اما در معرض بودن به معنی نفوذ نیست. اول وصله کنید، بعد مراحل راستی‌آزمایی بالا را اجرا کنید؛ فقط بر اساس مدرک، هاست را نفوذشده فرض کنید و اگر مدرکی یافتید، بازسازی کنید نه پاک‌سازی.

هاستم می‌گوید PHP 8.3.6. وصله شده یا نه؟

به بیلد بستگی دارد. بسته‌های توزیع اصلاحات CVE را همراه خود دارند و در عین حال شمارهٔ نسخهٔ upstream را حفظ می‌کنند، پس PHP 8.3.6 از Ubuntu 24.04 یا Debian می‌تواند از قبل شامل هر دو اصلاح باشد. نسخهٔ کامل بسته و سطر گزارش تغییراتی که CVE-2026-109618 و CVE-2026-109619 را نام می‌برد را بخواهید؛ روی پلتفرم‌های مدیریت‌شده به‌جایش تاریخ وصله را بخواهید.

به‌روزرسانی افزونه، قالب یا فریم‌ورک مرا از PHP2Shell محافظت می‌کند؟

نه. هر دو اشکال در راه‌اندازی و جمع‌کردن درخواست در مفسر PHP هستند، نه در کد برنامه. به‌روزرسانی برنامه‌ها همچنان بهداشت خوبی است و WAF هم ترافیک فرصت‌طلبانه را کُند می‌کند، اما فقط ارتقای مفسر آسیب‌پذیری را از بین می‌برد.

می‌توانم فقط محدودیت حافظه را پایین‌تر بیاورم تا جلوی اشکال اتمام حافظه گرفته شود؟

برعکس. راهنمای موقت اطلاعیه برای CVE-2026-109618 این است که جلوی ساقط‌شدن PHP روی سقف حافظهٔ خودش گرفته شود — memory_limit = -1، به شکلی تنظیم شود که کد برنامه نتواند آن را بازنویسی کند — سپس پیچیدگی درخواست در پروکسی سقف‌گذاری شود و ورکر با محدودیت container یا cgroup مهار شود. محدودیت سفت‌تر در PHP درست داخل همان حالت شکستی قرار دارد که مورد سوءاستفاده قرار می‌گیرد.

ما روی PHP 8.1 یا قدیمی‌تر هستیم که نسخهٔ upstream نگرفت. حالا چه کنیم؟

اگر می‌توانید به یک شاخهٔ پشتیبانی‌شده بروید؛ پاسخ ماندگار همین است. اگر نمی‌توانید، اصلاح را از توزیع یا سازندهٔ خود بگیرید که تنها منبع واقع‌بینانه است، یا اگر از سورس بیلد می‌گیرید، باک‌پورت‌های سورس حداقلی‌ای را که پروژهٔ PHP برای 7.4، 8.0 و 8.1 منتشر کرده اعمال کنید. این تصمیم را ثبت کنید، چون هر ماهی که آن را نگه دارید، پروفایل ریسک‌تان را تغییر می‌دهد.

ارتقای PHP 8.3 به 8.3.36 برای یک فروشگاه زنده ریسک دارد؟

یک به‌روزرسانی امنیتی هم‌نسخه، باینری مفسر را عوض می‌کند نه زبان را، پس بیشتر برنامه‌ها بی‌تأثیر می‌مانند. ریسک عملیاتی است: مجموعه‌بسته‌های ناقص، ری‌استارت فراموش‌شده یا پیکربندی‌ای که فقط زیر بار خودش را نشان می‌دهد. اسنپ‌شات بگیرید، کل مجموعهٔ بسته‌های PHP را ارتقا دهید، فرایند سرو‌دهندهٔ درخواست را ری‌استارت و راستی‌آزمایی کنید — و وقتی پلتفرم پیچیده است، اول در استیجینگ انجامش دهید.

منابع

می‌خواهید ارتقا را برایتان انجام دهیم؟ برای گفت‌وگو درباره وصله‌کردن، بازرسی نسخه‌ها، مهاجرت به یک پلتفرم PHP مدیریت‌شده و وصله‌شده یا زیرساخت پیرامون آن، با ما تماس بگیرید یا شمارهٔ +90 505 679 78 03 را بگیرید.