وردپرس

آسیب‌پذیری بحرانی وردپرس (wp2shell)؛ چه شد، چه کنیم و چطور بفهمیم هک شده‌ایم

سعید حسینیسعید حسینی۲۹ تیر ۱۴۰۵۱۵ دقیقه مطالعه
آسیب‌پذیری بحرانی وردپرس (wp2shell)؛ چه شد، چه کنیم و چطور بفهمیم هک شده‌ایم

روز ۱۷ جولای ۲۰۲۶ (۲۶ تیر ۱۴۰۵) تیم امنیتی وردپرس سه نسخه‌ی اضطراری منتشر کرد: ۷.۰.۲، ۶.۹.۵ و ۶.۸.۶. دلیلش یک زنجیره‌ی آسیب‌پذیری در هسته‌ی خود وردپرس بود — نه در یک افزونه یا قالب.

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

⚡ اگر وقت ندارید، فقط همین را بخوانید

به پیشخوان وردپرس بروید و شماره‌ی نسخه را ببینید. اگر روی ۷.۰.۲، ۶.۹.۵، ۶.۸.۶ یا بالاتر هستید، وصله شده‌اید و کاری لازم نیست.

اگر روی ۷.۰.۰–۷.۰.۱ یا ۶.۹.۰–۶.۹.۴ هستید، همین حالا به‌روزرسانی کنید — این نسخه‌ها در معرض زنجیره‌ی اجرای کد از راه دور بودند.

اگر روی ۶.۸.۰–۶.۸.۵ هستید فقط تزریق SQL شما را تهدید می‌کند (نه RCE) — ولی باز هم به ۶.۸.۶ بروید. نسخه‌های قدیمی‌تر از ۶.۸ اصلاً تحت تأثیر نیستند.

دقیقاً چه اتفاقی افتاد؟

دو آسیب‌پذیری جداگانه کشف و هم‌زمان وصله شدند. جداگانه بودنشان مهم است، چون دامنه‌ی تأثیرشان یکی نیست:

شناسهنوعنسخه‌های آسیب‌پذیرکاشف
CVE-2026-60137تزریق SQL در WP_Query۶.۸.۰–۶.۸.۵ · ۶.۹.۰–۶.۹.۴ · ۷.۰.۰–۷.۰.۱تیم TF1T، dtro و haongo
CVE-2026-63030سردرگمی مسیر در REST API که به اجرای کد ختم می‌شود۶.۹.۰–۶.۹.۴ · ۷.۰.۰–۷.۰.۱Adam Kues از Assetnote / Searchlight Cyber

محقق دوم نام wp2shell را روی این کشف گذاشته است. گزارش‌ها از طریق برنامه‌ی باگ‌بانتی وردپرس در HackerOne ثبت شده‌اند و متن انتشار نسخه را Aaron Jorbin نوشته است.

جدول نسخه‌های آسیب‌پذیر وردپرس
کدام نسخه در برابر کدام آسیب‌پذیری قرار دارد — بر اساس یادداشت‌های رسمی انتشار wordpress.org

چطور بفهمم چه نسخه‌ای دارم؟

ساده‌ترین راه پیشخوان است: پیشخوان ← به‌روزرسانی‌ها، یا گوشه‌ی پایین-راست صفحه‌ی مدیریت. اما اگر به پیشخوان دسترسی ندارید (مثلاً سایت از کار افتاده یا رمز را ندارید)، دو راه دیگر هست.

از طریق SSH با WP-CLI:

wp core version

یا مستقیم از روی فایل — این فایل در ریشه‌ی نصب وردپرس است و همیشه شماره‌ی نسخه را دارد:

grep "wp_version =" wp-includes/version.php

در سی‌پنل، اگر SSH ندارید، از File Manager فایل wp-includes/version.php را باز کنید و دنبال خط $wp_version بگردید.

⚠️ به آنچه در صفحه‌ی سایت می‌بینید اعتماد نکنید. بسیاری از افزونه‌های امنیتی شماره‌ی نسخه را از تگ generator در سورس HTML حذف می‌کنند. نبودن شماره در سورس صفحه به‌هیچ‌وجه یعنی «به‌روز هستم» نیست — از پیشخوان یا خود فایل بررسی کنید.

چطور به‌روزرسانی کنم؟

در حالت عادی، پیشخوان ← به‌روزرسانی‌ها ← هم‌اکنون به‌روزرسانی کن کافی است. با WP-CLI:

wp core update
wp core update-db
wp core version

اگر روی شاخه‌ی ۶.۸ هستید و نمی‌خواهید به نسخه‌ی اصلی بعدی بپرید، می‌توانید نسخه را دقیق مشخص کنید:

wp core update --version=6.8.6

قبل از هر به‌روزرسانی‌ای، پشتیبان بگیرید — هم از فایل‌ها و هم از دیتابیس. اگر روش مطمئنی ندارید، راهنمای پشتیبان‌گیری از سایت را ببینید. در هاست‌های هستینو می‌توانید از سی‌پنل هم بکاپ کامل بگیرید؛ مراحلش در آموزش سی‌پنل آمده است.

«به‌روزرسانی اجباری» یعنی چه — و چرا نباید به آن تکیه کنید

وردپرس در اطلاعیه‌ی رسمی نوشته است که «با توجه به شدت، تیم WordPress.org به‌روزرسانی اجباری را از طریق سامانه‌ی به‌روزرسانی خودکار برای سایت‌های دارای نسخه‌های آسیب‌پذیر فعال کرده است.»

یعنی بسیاری از سایت‌ها بدون هیچ دخالتی وصله شده‌اند. اما اینجا باید صادق باشم: اطلاعیه‌ی رسمی توضیح نمی‌دهد این فشار اجباری با سایت‌هایی که به‌روزرسانی خودکار را غیرفعال کرده‌اند چه می‌کند. و منطقاً، سایت‌هایی که در این وضعیت‌ها هستند نمی‌توانند چنین به‌روزرسانی‌ای دریافت کنند:

  • ثابت AUTOMATIC_UPDATER_DISABLED در wp-config.php فعال است
  • ثابت DISALLOW_FILE_MODS فعال است — این مورد فریبنده است، چون در بسیاری از راهنماهای «سخت‌سازی وردپرس» توصیه می‌شود، اما جلوی به‌روزرسانی‌های امنیتی اجباری را هم می‌گیرد. اگر از آن استفاده می‌کنید، حتماً وصله‌ها را از طریق WP-CLI اعمال کنید
  • سیستم فایل فقط-خواندنی است (بعضی استقرارهای کانتینری یا Git-based)
  • دسترسی خروجی سرور به api.wordpress.org بسته است
  • کران وردپرس (wp-cron) از کار افتاده و هیچ‌وقت اجرا نمی‌شود

پس فرض نکنید وصله شده‌اید. بروید و نسخه را با چشم خودتان ببینید. این کار سی ثانیه طول می‌کشد.

باگ واقعاً چه بود؟ (بخش فنی)

اینجا نکته‌ای هست که بیشتر مطالب منتشرشده در این‌باره از آن عبور کرده‌اند: محقق عمداً جزئیات فنی را منتشر نکرد. در گزارش رسمی Searchlight Cyber آمده: «با توجه به شدت باگ و برای اینکه به مدافعان فرصت وصله دهیم، فعلاً جزئیات فنی را منتشر نمی‌کنیم.»

اما وصله‌ها متن‌باز هستند. آنچه در ادامه می‌خوانید از مقایسه‌ی مستقیم کد نسخه‌های وصله‌شده با نسخه‌های آسیب‌پذیر در مخزن WordPress/wordpress-develop استخراج شده — نه از حدس و گمان.

۱) تزریق SQL: یک باگ کلاسیک «سردرگمی نوع»

کد آسیب‌پذیر در WP_Query چنین بود:

if ( is_array( $query_vars['author__not_in'] ) ) {
    $query_vars['author__not_in'] = array_unique( array_map( 'absint', $query_vars['author__not_in'] ) );
    sort( $query_vars['author__not_in'] );
}
$author__not_in = implode( ',', (array) $query_vars['author__not_in'] );
$where         .= " AND {$wpdb->posts}.post_author NOT IN ($author__not_in) ";

خطا را می‌بینید؟ پاک‌سازی — یعنی absint که هر مقدار را به عدد صحیح تبدیل می‌کند — داخل شرط is_array() قرار دارد. اما خط آخر، که مقدار را مستقیم داخل کوئری SQL می‌چسباند، بیرون شرط است و همیشه اجرا می‌شود.

پس اگر مهاجم به‌جای یک آرایه، یک رشته بفرستد، کل شاخه‌ی پاک‌سازی نادیده گرفته می‌شود. سپس (array) آن رشته را دست‌نخورده در یک آرایه می‌پیچد، implode همان رشته‌ی خام را برمی‌گرداند، و مقدار بدون هیچ فیلتری وارد کوئری می‌شود.

وصله ساده است: wp_parse_id_list() حالا بدون قید و شرط اجرا می‌شود و شرط SQL فقط وقتی اضافه می‌شود که فهرست نهایی خالی نباشد.

یک نکته‌ی مهم: طبق توضیح NVD، این آسیب‌پذیری به‌تنهایی نیازمند آن است که یک افزونه یا قالب، ورودی نامعتبر را به این پارامتر پاس بدهد. به همین دلیل، به‌عنوان یک باگ مستقل، بهره‌برداری از آن آسان نیست.

۲) زنجیره‌ی batch: یک خط جاافتاده

این یکی زیباتر — و ترسناک‌تر — است. REST API وردپرس امکانی به نام batch دارد: چند درخواست را در یک بسته می‌فرستید و سرور یکی‌یکی پردازششان می‌کند.

در پیاده‌سازی، دو آرایه‌ی موازی نگهداری می‌شود: $matches (مسیر و هندلر هر زیردرخواست) و $validation (نتیجه‌ی اعتبارسنجی). این دو بر اساس ایندکس با هم مصرف می‌شوند — یعنی عنصر شماره‌ی ۳ یکی باید با عنصر شماره‌ی ۳ آن یکی جفت باشد.

اما وقتی یک زیردرخواست خطا می‌داد، کد فقط به $validation اضافه می‌کرد و از $matches رد می‌شد. کل وصله یک خط است:

if ( is_wp_error( $single_request ) ) {
    $has_error    = true;
+   $matches[]    = $single_request;
    $validation[] = $single_request;
    continue;
}

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

نمودار ناهم‌گام شدن آرایه‌های موازی در batch
یک زیردرخواست خراب، همه‌چیز را یک خانه جابه‌جا می‌کند — و مجوزِ درخواست بعدی را به درخواست قبلی می‌دهد

یعنی مهاجم می‌تواند ترتیب را طوری بچیند که یک عملیات پرمجوز، با مجوزِ یک عملیات بی‌خطر تأیید شود. این همان «سردرگمی مسیر» است.

آنچه هنوز عمومی نیست: هیچ منبع اولیه‌ای توضیح نداده که این دو باگ دقیقاً چطور به اجرای کد ختم می‌شوند. وصله‌ها این مرحله را روشن نمی‌کنند و محقق هم منتشرش نکرده. هر مطلبی که مدعی است زنجیره‌ی کامل RCE را قدم‌به‌قدم توضیح می‌دهد، دارد حدس می‌زند. ما هم حدس نمی‌زنیم.

چرا نسخه‌ی ۶.۸ در برابر RCE مصون است؟

این بخش ظرافتی دارد که حتی در گزارش‌های تخصصی هم اشتباه نقل شده است.

حدس طبیعی این است که «۶.۸.۶ فقط WP_Query را عوض کرده، چون فقط SQLi روی ۶.۸ اثر دارد.» اما این غلط است. بررسی diff نشان می‌دهد ۶.۸.۶ فایل class-wp-rest-server.php را هم تغییر می‌دهد.

دلیلش جالب است: در نسخه‌ی ۶.۸.۵، آن بلوک مدیریت خطا با continue اصلاً وجود نداشت. آن بلوک در نسخه‌ی ۶.۹ اضافه شده بود. و چون بلوکی نبود که زودهنگام continue کند، آرایه‌ها هرگز نمی‌توانستند ناهم‌گام شوند — دقیقاً به همین دلیل ۶.۸ در برابر CVE-2026-63030 مصون است.

پس تغییر REST در ۶.۸.۶ یک «سخت‌سازی پیشگیرانه» است، نه رفع آسیب‌پذیری. این را گفتم چون اگر جایی خواندید «۶.۸.۶ فقط دیتابیس را وصله کرده»، حالا می‌دانید ماجرا دقیق‌تر از آن است.

خودِ وردپرس در صفحه‌ی نسخه‌ی ۷.۰.۲ این‌طور جمع‌بندی کرده: «وردپرس ۶.۹ تحت تأثیر هر دو آسیب‌پذیری است... وردپرس ۶.۸ فقط تحت تأثیر آسیب‌پذیری اول است... نسخه‌های پیش از ۶.۸ تحت تأثیر نیستند.»

ماجرای نمره‌های ضدونقیض CVSS

اگر چند مطلب مختلف درباره‌ی این آسیب‌پذیری بخوانید، اعداد متناقضی می‌بینید. دلیلش این است که مؤسسه‌ی NIST هنوز به هیچ‌کدام نمره نداده و دو مرجع دیگر که نمره داده‌اند، دقیقاً برعکس هم قضاوت کرده‌اند:

آسیب‌پذیرینمره‌ی WPScanنمره‌ی CISA-ADPنمره‌ی NIST
CVE-2026-63030 (RCE)۹.۸ بحرانی۷.۵ بالا
CVE-2026-60137 (SQLi)۵.۹ متوسط۹.۱ بحرانی

این تناقض تصادفی نیست. WPScan به زنجیره‌ی RCE نمره‌ی بالا داده چون تأثیر نهایی‌اش کامل است؛ اما به SQLi نمره‌ی پایین‌تر داده چون بهره‌برداری از آن به‌تنهایی شرط دارد (همان نیاز به افزونه‌ای که ورودی خام پاس بدهد). CISA از زاویه‌ی دیگری نگاه کرده است.

نتیجه‌ی عملی برای شما: هر مقاله‌ای که یک عدد قطعی و بی‌قیدوشرط به این آسیب‌پذیری نسبت بدهد، تصویر ناقصی می‌دهد. ولی این بحث نمره‌گذاری هیچ تغییری در کاری که باید بکنید نمی‌دهد: به‌روزرسانی کنید.

آیا سوءاستفاده‌ی فعالی در جریان است؟

اینجا هم ترجیح می‌دهم دقیق باشم تا هیجان‌انگیز.

اطلاعیه‌ی رسمی وردپرس هیچ ادعایی درباره‌ی سوءاستفاده‌ی فعال نمی‌کند — نه می‌گوید هست، نه می‌گوید نیست؛ اصلاً به موضوع نمی‌پردازد. شرکت Rapid7 در تاریخ ۱۷ جولای نوشت که از «سوءاستفاده‌ی تأییدشده‌ی عمومی در دنیای واقعی» اطلاعی ندارد، هرچند انتظار داشت به‌زودی کد اثبات مفهوم منتشر شود. کلادفلر هم قوانین WAF خود را ساعت ۱۷:۰۳ به وقت جهانی همان روز فعال کرد، بدون گزارش ترافیک مخرب مشاهده‌شده.

آن ادعای پرتکرار که «ظرف ۲۴ ساعت مورد سوءاستفاده قرار گرفت» را در هیچ منبع اولیه‌ای پیدا نکردیم.

اما — و این «اما» مهم است — نبودِ گزارشِ سوءاستفاده به معنای امن بودن نیست. وصله‌ها متن‌باز هستند و همان کاری که ما برای نوشتن بخش فنی بالا کردیم (خواندن diff)، برای یک مهاجم هم ممکن است. تاریخ نشان داده فاصله‌ی بین انتشار وصله و انتشار اکسپلویت معمولاً روزها است، نه ماه‌ها.

چطور بفهمم قبلاً نفوذ شده‌ام؟

وردپرس هیچ راهنمای رسمی برای این کار منتشر نکرده است. اما قبل از هر دستوری، باید یک تصور غلط رایج را کنار بگذاریم.

❗ لاگ دسترسی، تبرئه‌تان نمی‌کند

گام‌های تعیین‌کننده‌ی این حمله داخل بدنه‌ی درخواست POST منتقل می‌شوند — و لاگ دسترسی آپاچی و انجینکس بدنه‌ی درخواست را اصلاً ثبت نمی‌کند. علاوه بر این، بعضی وب‌شل‌ها بعد از اجرا خودشان را حذف می‌کنند.

نتیجه: یک grep تمیز روی لاگ‌ها هیچ چیزی را اثبات نمی‌کند. مدرک اصلی در دیتابیس است، نه در لاگ. اگر این را ندانید، ممکن است با خیال راحت از یک سایت آلوده رد شوید.

گام اول — نشانه‌های شناخته‌شده در دیتابیس. تیم Eye Security پس از بررسی موارد واقعی، نشانه‌های مشخصی منتشر کرده است. حساب‌های مدیر ساخته‌شده توسط این ابزار معمولاً نام کاربری با پیشوند wp2_ یا w2s_ دارند و ایمیلشان روی دامنه‌های @wp2shell.invalid یا @wp2shell.shellcode.lol است.

wp user list --role=administrator --fields=ID,user_login,user_email,user_registered

wp db query "SELECT ID,user_login,user_email,user_registered FROM wp_users
  WHERE user_login LIKE 'wp2\_%' OR user_login LIKE 'w2s\_%'
     OR user_email LIKE '%wp2shell%';"

روی پیشوند تطبیق بدهید، نه رشته‌ی دقیق — مهاجمان نام‌ها را تغییر می‌دهند. و مستقل از این الگوها، هر حساب مدیری که نمی‌شناسید یا بعد از ۱۷ جولای ساخته شده و کار خودتان نبوده، مشکوک است.

دو نشانه‌ی دیگر در جدول wp_options: ردیف‌های oembed_cache که به خودِ سایت اشاره می‌کنند (loopback)، و ردیف‌های customize_changeset با شناسه‌ی والدِ غیرعادی بزرگ.

گام دوم — رمزهای اپلیکیشن. این مورد را اغلب فراموش می‌کنند و دقیقاً به همین دلیل محبوب مهاجمان است: رمزهای اپلیکیشن با عوض کردن رمز عبور باطل نمی‌شوند و راه بازگشت مهاجم را باز نگه می‌دارند. در usermeta با کلید _application_passwords ذخیره می‌شوند:

wp db query "SELECT user_id, meta_value FROM wp_usermeta
  WHERE meta_key = '_application_passwords';"

گام سوم — بررسی یکپارچگی فایل‌ها. این دستور فایل‌های هسته را با نسخه‌ی رسمی مقایسه می‌کند:

wp core verify-checksums
wp plugin verify-checksums --all

محدودیت مهم این ابزار — مخصوصاً در ایران

دستور wp plugin verify-checksums فقط افزونه‌هایی را بررسی می‌کند که در مخزن رسمی wordpress.org میزبانی می‌شوند. هر افزونه‌ی تجاری، سفارشی یا نال‌شده بدون هیچ هشداری نادیده گرفته می‌شود.

بدتر اینکه برای قالب‌ها اصلاً چنین قابلیتی وجود ندارد — دستور wp theme verify-checksums موجود نیست. با توجه به رواج قالب‌ها و افزونه‌های نال‌شده در بازار ایران، این یک نقطه‌ی کور واقعی است: بخش بزرگی از کدِ سایت شما ممکن است هرگز راستی‌آزمایی نشود.

گام چهارم — فایل‌های مشکوک. اول جایی که اصلاً نباید فایل PHP باشد:

find wp-content/uploads -type f \( -name "*.php" -o -name "*.phtml" \)

این دستور تقریباً همیشه باید خروجی خالی بدهد.

حالا یک ترفند مهم. جست‌وجو بر اساس mtime (زمان تغییر) به‌تنهایی قابل اعتماد نیست، چون مهاجم می‌تواند با touch آن را به عقب برگرداند. اما ctime را نمی‌تواند دستکاری کند — و جالب اینکه خودِ عملِ تغییر mtime، مقدار ctime را به‌روز می‌کند. پس ترکیب «mtime قدیمی + ctime جدید» نشانه‌ی قوی جعل زمان است:

find /home/user/public_html -type f -name "*.php" -ctime -7 ! -mtime -7 \
  -printf '%TY-%Tm-%Td  %CY-%Cm-%Cd  %p\n'

(گزینه‌های -printf و -newermt مخصوص نسخه‌ی GNU از find هستند و روی برخی سیستم‌ها موجود نیستند.)

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

grep -rEn --include='*.php' '(eval|assert|system|exec|shell_exec|passthru|preg_replace|create_function)[[:space:]]*\([[:space:]]*.{0,40}\$_(POST|GET|REQUEST|COOKIE|SERVER)' /home/user/public_html

حتماً از تک‌کوتیشن استفاده کنید؛ شکل دابل‌کوتیشن، کاراکترهای فرار را در bash خراب می‌کند.

گام پنجم — لاگ‌ها (به‌عنوان شاهد مکمل، نه دلیل). با یادآوری هشدار بالا، دیدن حجم غیرعادی درخواست به مسیر batch از یک IP ناشناس هنوز ارزش بررسی دارد. در سی‌پنل مسیر لاگ بسته به نسخه فرق می‌کند، پس همه را چک کنید:

/etc/apache2/logs/domlogs/<user>/<domain>     # EasyApache 4
/usr/local/apache/domlogs/<domain>            # EasyApache 3
~/access-logs/

grep -i "batch/v1" access.log | head -50
zgrep -i "batch/v1" access.log.*.gz            # لاگ‌های آرشیوشده را فراموش نکنید

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

نکته‌ی امنیتی درباره‌ی خود WP-CLI: روی سروری که به نفوذ مشکوک هستید، دستورات را با --allow-root اجرا نکنید — این کار کدِ افزونه‌ها (که ممکن است آلوده باشند) را با دسترسی روت اجرا می‌کند. به‌جایش با کاربر خود سایت اجرا کنید و هنگام بررسی، افزونه‌ها و قالب‌ها را از مدار خارج کنید:
sudo -u siteuser -i -- wp --path=/home/siteuser/public_html --skip-plugins --skip-themes user list

تیم Searchlight Cyber یک ابزار آنلاین برای بررسی آسیب‌پذیر بودن سایت منتشر کرده که در گزارش رسمی خودشان به آن لینک داده‌اند. اگر خواستید از آن استفاده کنید، از طریق همان گزارش رسمی در slcyber.io واردش شوید، نه با جست‌وجوی نام دامنه. بعد از هر آسیب‌پذیری پرسروصدا، سایت‌های تقلبی «بررسی کنید هک شده‌اید؟» قارچ‌وار سبز می‌شوند و هدفشان جمع‌آوری فهرست سایت‌های آسیب‌پذیر است.

اگر نفوذ کرده بودند، چه کنم؟

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

  1. سایت را موقتاً از دسترس خارج کنید یا پشت حالت تعمیر ببرید
  2. پشتیبان کامل بگیرید — حتی از نسخه‌ی آلوده (برای بررسی بعدی لازم است)
  3. هسته را از نو نصب کنید: wp core download --force
  4. رمز همه‌ی کاربران و رمز دیتابیس را عوض کنید (توجه: این دستور فلگ --all ندارد):
    wp user reset-password $(wp user list --format=ids)
  5. رمزهای اپلیکیشن را باطل کنید — این‌ها با تغییر رمز عبور از بین نمی‌روند و رایج‌ترین راه بازگشت مهاجم‌اند:
    wp user application-password delete <user> --all
  6. کلیدهای امنیتی wp-config.php (همان SALTها) را بازتولید کنید تا همه‌ی نشست‌های فعال باطل شوند
  7. افزونه‌ها و قالب‌های ناشناس یا غیرفعال را حذف کنید

مراحل کامل‌تر پاک‌سازی را در راهنمای سایت وردپرسی هک‌شده نوشته‌ایم.

سایر آسیب‌پذیری‌های مهم این ماه

wp2shell تنها خبر امنیتی این هفته‌ها نبود. دو مورد دیگر هم ارزش دانستن دارند:

miniOrange OAuth SSO — بدون وصله

آسیب‌پذیری CVE-2026-57807 یک دور زدن کامل احراز هویت است؛ مهاجم بدون داشتن هیچ حسابی می‌تواند از مسیر بازیابی رمز عبور به‌عنوان هر کاربری — از جمله مدیر — وارد شود. Patchstack به آن نمره‌ی ۹.۸ داده و طبق NVD همه‌ی نسخه‌ها تا ۳۸.۵.۸ را در بر می‌گیرد.

تا زمان نگارش این مطلب، هیچ وصله‌ای اعلام نشده است. توصیه‌ی عملی: اگر این افزونه را دارید و به آن نیاز حیاتی ندارید، غیرفعال و حذفش کنید.

یک ابهام را هم صادقانه بگویم: نام محصول در سابقه‌ی CVE با افزونه‌ی رایگان موجود در مخزن وردپرس یکسان است، اما شماره‌ی نسخه‌ی آن مخزن روی شاخه‌ی کاملاً متفاوتی (۶.۲۶.x) است. نتوانستیم قطعی کنیم که آیا ۳۸.۵.x نسخه‌ی سازمانی جداگانه‌ای است یا شماره‌ی نسخه در سابقه‌ی CVE اشتباه ثبت شده. اگر از این افزونه استفاده می‌کنید، مستقیماً با سازنده تماس بگیرید.

کمپین WP-SHELLSTORM و افزونه‌ی Breeze

محققان سروری متعلق به یک گروه مهاجم را کشف کردند که ۲۲ روز باز مانده بود و فهرستی از ۱٫۴ میلیون دامنه‌ی هدف داشت؛ ۲۵٬۱۹۵ نفوذ موفق تأیید شد. مهاجمان از ۲۷ آسیب‌پذیریِ شناخته‌شده استفاده می‌کردند.

پربازده‌ترین ابزارشان CVE-2026-3844 در افزونه‌ی کش Breeze بود (آپلود فایل دلخواه، نسخه‌های تا ۲.۴.۴، نمره‌ی ۹.۸). اما دو نکته‌ی مهم که معمولاً حذف می‌شود: این آسیب‌پذیری فقط زمانی قابل بهره‌برداری است که گزینه‌ی غیرپیش‌فرضِ «Host Files Locally – Gravatars» فعال باشد، و این باگ در آوریل ۲۰۲۶ وصله شده بود.

یعنی این کمپین داستان یک آسیب‌پذیری روز-صفر نیست؛ داستان تأخیر در نصب وصله است. و همین دقیقاً درسِ اصلی این مقاله است.

چطور دفعه‌ی بعد جلوتر باشیم؟

هیچ‌کس نمی‌تواند جلوی کشف آسیب‌پذیری در نرم‌افزار را بگیرد. کاری که می‌شود کرد، کوتاه کردن فاصله‌ی بین «وصله منتشر شد» و «سایت من وصله شد» است:

  • به‌روزرسانی خودکار نسخه‌های جزئی را روشن بگذارید. وردپرس به‌صورت پیش‌فرض این کار را می‌کند و دقیقاً برای همین سناریوها طراحی شده است.
  • افزونه‌های بلااستفاده را حذف کنید، نه فقط غیرفعال. افزونه‌ی غیرفعال هم روی دیسک است و کدش می‌تواند مستقیماً فراخوانی شود.
  • پشتیبان‌گیری خودکار و آزموده داشته باشید. بکاپی که هیچ‌وقت بازیابی‌اش را امتحان نکرده‌اید، بکاپ نیست.
  • خبرنامه‌های امنیتی را دنبال کنید — Patchstack، Wordfence و خودِ wordpress.org/news.
  • اجرای فایل PHP در پوشه‌ی آپلودها را ببندید. این یک تنظیم ساده در سطح وب‌سرور است و جلوی بخش بزرگی از وب‌شل‌ها را می‌گیرد.
  • سطح دسترسی wp-config.php را درست بگذارید. مستندات رسمی وردپرس مقدار 400 یا 440 را توصیه می‌کند — نه 600 و 640 که معمولاً تکرار می‌شود.
  • از قالب و افزونه‌ی نال‌شده استفاده نکنید. همان‌طور که بالاتر دیدیم، این‌ها نه‌تنها اغلب خودشان آلوده‌اند، بلکه از چتر ابزارهای راستی‌آزمایی هم بیرون می‌مانند.

راهکارهای بیشتر را در ۱۰ راهکار ضروری امنیت وردپرس جمع کرده‌ایم.

هاست وردپرس هستینو

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

تفاوت هاست وردپرس با هاست معمولی را در این مقاله توضیح داده‌ایم.

سوالات متداول

سایت من روی وردپرس ۶.۵ است. باید نگران باشم؟
در مورد این دو آسیب‌پذیری خیر — وردپرس رسماً اعلام کرده نسخه‌های پیش از ۶.۸ تحت تأثیر نیستند. اما نسخه‌ی ۶.۵ از آسیب‌پذیری‌های قبلی دیگری رنج می‌برد و به‌هرحال باید به‌روزرسانی شود.

به‌روزرسانی خودکار دارم. کاری لازم است؟
احتمالاً وصله شده‌اید، ولی حتماً تأیید کنید. سایت‌هایی که سیستم فایل فقط-خواندنی دارند، دسترسی‌شان به api.wordpress.org بسته است، یا wp-cron در آن‌ها کار نمی‌کند، ممکن است به‌روزرسانی را دریافت نکرده باشند.

به‌روزرسانی سایتم را خراب می‌کند؟
این‌ها نسخه‌های جزئی امنیتی هستند و تغییر شکسته در آن‌ها نادر است. با این‌حال قبل از هر به‌روزرسانی پشتیبان بگیرید — به‌خصوص اگر قالب یا افزونه‌ی سفارشی دارید.

فایروال یا افزونه‌ی امنیتی کافی نیست؟
فایروال لایه‌ی ارزشمندی است و کلادفلر هم قوانین اختصاصی برای همین مورد منتشر کرد، اما جایگزین وصله نیست. طبق گزارش Patchstack، دفاع‌های سطح هاستینگ تنها حدود ۱۲٪ از آسیب‌پذیری‌های فعالانه مورد سوءاستفاده را مسدود می‌کنند.

از کجا بفهمم افزونه‌هایم آسیب‌پذیرند؟
پایگاه‌های Patchstack و WPScan را می‌توانید بر اساس نام افزونه جست‌وجو کنید. دستور wp plugin list --update=available هم فهرست افزونه‌های نیازمند به‌روزرسانی را می‌دهد.

اگر نتوانم فوراً به‌روزرسانی کنم چه کنم؟
به‌عنوان راهکار موقت، دسترسی به مسیر batch را در سطح وب‌سرور ببندید. اما حتماً هر دو شکل را ببندید، وگرنه راه باز می‌ماند: هم مسیر /wp-json/batch/v1 و هم شکل پارامتری ?rest_route=/batch/v1. قانونی که فقط مسیر را ببندد، دومی را رد می‌کند. این‌ها راهکار موقت‌اند، نه جایگزین وصله.

بهتر نیست کلاً REST API را غیرفعال کنم؟
خیر، و این توصیه‌ی خطرناکی است که در چند مطلب دیده می‌شود. مستندات رسمی وردپرس صراحتاً می‌گوید: «نباید REST API را غیرفعال کنید؛ این کار بخش‌هایی از پیشخوان وردپرس را که به آن وابسته‌اند از کار می‌اندازد.» فقط مسیرهای مشخصِ batch را ببندید، نه کل API را.

جمع‌بندی

خلاصه‌ی عملی این مقاله در یک جمله است: نسخه‌ی وردپرس خود را همین حالا چک کنید و اگر زیر ۷.۰.۲ / ۶.۹.۵ / ۶.۸.۶ هستید، به‌روزرسانی کنید.

اما درس بلندمدت‌تر جای دیگری است. کمپین WP-SHELLSTORM با ۲۵ هزار سایت قربانی، از یک آسیب‌پذیری روز-صفر استفاده نکرد — از باگی استفاده کرد که ماه‌ها قبل وصله شده بود و مدیران سایت‌ها آن را نصب نکرده بودند. wp2shell هم امروز وصله دارد. تنها چیزی که تعیین می‌کند سایت شما در فهرست قربانیان بعدی باشد یا نه، این است که چقدر سریع آن وصله را نصب کنید.

امنیت وردپرس یک پروژه‌ی یک‌باره نیست؛ یک عادت است.


منابع: اطلاعیه‌ی رسمی انتشار وردپرس ۷.۰.۲ · سوابق CVE-2026-63030 و CVE-2026-60137 در NVD · گزارش Searchlight Cyber · راهنمای مدافعان از Eye Security (نشانه‌های دیتابیسی) · تحلیل Cloudflare · کد وصله‌ها در مخزن wordpress-develop. بخش فنی این مقاله از مقایسه‌ی مستقیم کد نسخه‌های وصله‌شده استخراج شده است.

برچسب‌ها:وردپرسامنیت وردپرسآسیب‌پذیریCVEwp2shellامنیت سایت
سعید حسینی
نویسنده
سعید حسینی
کارشناس وردپرس و بهینه‌سازی سایت

سعید بیش از ۸ سال است که روی طراحی، سرعت و بهینه‌سازی سایت‌های وردپرسی کار می‌کند. علاقه‌اش به تجربه‌ی کاربری و سئو باعث شده آموزش‌های کاربردی و ساده برای صاحبان سایت بنویسد تا هر کسی بتواند سایتی سریع و حرفه‌ای داشته باشد.

مقاله‌های بیشتر از سعید حسینی ←

مقاله‌های مرتبط

به کمک نیاز دارید؟

تیم پشتیبانی ما ۲۴ ساعته آماده پاسخگویی به سوالات شما و ارائه راهنمایی‌های تخصصی است.

کمک فروش هاستینو

۲۴/۷/۳۶۵ از طریق ویجت چت

گفتگو کنید

چت پشتیبانی مشتریان

۲۴/۷/۳۶۵ از طریق پنل

برو به پنل

ایمیل پشتیبانی مشتریان

۲۴/۷/۳۶۵ از طریق پنل

برو به پنل

پشتیبانی با هوش مصنوعی

۲۴/۷/۳۶۵ کمک فوری هوش مصنوعی

امتحان دستیار هوشمند

ما باور داشتیم دنیای هاستینگ نیاز به یک تحول بزرگ دارد — و افتخار می‌کنیم آغازگر این تغییر بوده‌ایم.