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

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

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

۱. سایت‌ها معمولاً از کجا ضربه می‌خورند

پیش از فهرست کارها، بد نیست بدانید مهاجم واقعاً از کجا وارد می‌شود. تقریباً همه موارد در چند دسته محدود جا می‌گیرند:

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

هر بخش این مقاله دقیقاً یکی از همین مسیرها را می‌بندد.

۲. هسته، افزونه‌ها و قالب‌ها را به‌روز نگه دارید

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

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

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

۳. قالب و افزونه را از منبع درست تهیه کنید

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

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

دو نکته عملی:

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

۴. هر چیزی را که استفاده نمی‌کنید حذف کنید

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

دیتابیس‌های بلااستفاده را هم پاک کنید. دیتابیسِ سایت قبلی یا نصب آزمایشی که فراموش شده، هم اطلاعات قدیمی (از جمله هش رمز کاربران) را نگه می‌دارد و هم معمولاً یک کاربر دیتابیس فعال کنارش باقی مانده است. فقط پیش از حذف، مطمئن شوید سایت فعلی به آن وصل نیست: نام دیتابیس در وردپرس در wp-config.php مقابل DB_NAME و در جوملا در configuration.php مقابل $db نوشته شده است. اول خروجی SQL بگیرید، بعد حذف کنید؛ و کاربر دیتابیسِ بی‌استفاده را هم جداگانه حذف کنید، چون حذف دیتابیس آن را پاک نمی‌کند.

۵. سایت را روی HTTPS ببرید

بدون HTTPS، کوکی نشست مدیر و اطلاعات ورود روی شبکه قابل شنود است؛ روی وای‌فای عمومی این یک ریسک واقعی است، نه تئوری. اگر هنوز گواهی ندارید، نصب SSL رایگان Let’s Encrypt در سی پنل ساده‌ترین نقطه شروع است. بعد از نصب گواهی، در وردپرس آدرس سایت را به https تغییر دهید و خط define('FORCE_SSL_ADMIN', true); را به wp-config.php اضافه کنید، و در جوملا گزینه اجبار به HTTPS را در تنظیمات کلی روشن کنید تا ورود به پیشخوان همیشه رمزنگاری‌شده باشد.

آنلاین سرور گواهینامه‌های SSL برند Certum را در سه نوع DV تک‌دامنه، DV وایلدکارت (دامنه اصلی به همراه تمام زیردامنه‌هایش) و EV ارائه می‌کند؛ زمان تحویل هر سه آنی است و هر سه امکان ReIssue دارند.

۶. حساب مدیریت را سخت کنید

حمله‌های brute force روی صفحه ورود مدیریت هر دو سیستم دائمی است. چند اقدام ساده تقریباً کل این ریسک را حذف می‌کند:

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

یک لایه قفل قبل از خود صفحه ورود

مؤثرترین کار این است که مهاجم اصلاً به فرم ورود نرسد. دو راه دارید.

محدود کردن به چند IP مشخص. اگر همه کاربران مدیریت از IP ثابتی کار می‌کنند، دسترسی به مسیر /wp-admin یا /administrator را در سطح وب‌سرور ببندید.

پیش از هر کاری دو نکته را جدی بگیرید، چون هر دو به قفل شدن خودتان بیرون از سایت ختم می‌شوند: اول IP واقعی امروزتان را ببینید (در ترمینال curl -4 ifconfig.co یا هر سایت «IP من چیست») و مطمئن شوید اینترنت خانگی یا موبایلتان IP ثابت دارد، چون در بیشتر سرویس‌های ایرانی IP متغیر است؛ دوم، راه دیگری برای برگرداندن فایل باز نگه دارید — File Manager کنترل‌پنل یا FTP — تا اگر بیرون ماندید بتوانید .htaccess را پاک کنید.

روی آپاچی ۲.۴ (نسخه‌ای که امروز روی سرورها نصب است) فایل .htaccess داخل همان پوشه این‌طور می‌شود:

Require ip 203.0.113.10
Require ip 198.51.100.0/24

این دستور فقط روی آپاچی ۲.۴ شناخته می‌شود. اگر سرور هنوز آپاچی ۲.۲ باشد، همین دو خط کل شاخه را با خطای ۵۰۰ از کار می‌اندازد؛ پس اول نسخه را از کنترل‌پنل ببینید و بعد از ذخیره، سایت را در یک مرورگر دیگر باز کنید. دستور معادل قدیمی روی ۲.۲ این بود:

# فقط برای Apache 2.2 — منسوخ است
Order Deny,Allow
Deny from all
Allow from 203.0.113.10

روی nginx فایل .htaccess اصلاً خوانده نمی‌شود و باید همین قانون را در بلوک کانفیگ سایت بنویسید. یک نکته مهم که معمولاً نادیده گرفته می‌شود: اگر بلوک را با ^~ بنویسید و داخلش پردازش PHP را تکرار نکنید، nginx دیگر سراغ بلوک عمومی .php$ نمی‌رود و فایل‌های PHP پنل مدیریت به‌جای اجرا شدن، به‌صورت متن ساده دانلود می‌شوند. شکل درست این است:

location ^~ /wp-admin/ {
    allow 203.0.113.10;
    deny all;

    # بدون این بلوک تودرتو، فایل‌های PHP اجرا نمی‌شوند
    location ~ .php$ {
        allow 203.0.113.10;
        deny all;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        # دقیقاً همان مقداری که در کانفیگ فعلی سایت هست:
        fastcgi_pass unix:/run/php/php-fpm.sock;
    }
}

برای جوملا به‌جای /wp-admin/ مسیر /administrator/ را بگذارید. هر تغییر کانفیگ nginx را هم اول تست کنید و بعد فقط reload بزنید، نه restart:

nginx -t && systemctl reload nginx

گذاشتن رمز روی خودِ پوشه مدیریت. اگر IP ثابت ندارید، به‌جای محدودیت IP یک احراز هویت ساده وب‌سرور روی پوشه بگذارید. در cPanel این کار با ابزار Directory Privacy و در دایرکت‌ادمین با Password Protected Directories انجام می‌شود و خودش فایل .htpasswd را می‌سازد. نتیجه این است که قبل از رسیدن به صفحه ورود وردپرس یا جوملا، مرورگر یک پنجره نام کاربری و رمز نشان می‌دهد و ربات‌های brute force همان‌جا متوقف می‌شوند.

دو نکته که معمولاً از قلم می‌افتد:

  • در وردپرس بستن پوشه wp-admin فایل wp-login.php را نمی‌بندد، چون این فایل در ریشه سایت است. همان محدودیت را جداگانه در .htaccess ریشه هم بگذارید — و چون این فایل کل سایت را کنترل می‌کند، حتماً اول از آن یک کپی بگیرید:
    <Files "wp-login.php">
    Require ip 203.0.113.10
    </Files>
  • فایل wp-admin/admin-ajax.php را استثنا کنید. بعضی افزونه‌ها در بخش عمومی سایت هم به آن درخواست می‌فرستند و بستن کامل wp-admin ممکن است فرم‌ها یا سبد خرید را از کار بیندازد. این چند خط را در همان .htaccess پوشه wp-admin اضافه کنید:
    <Files "admin-ajax.php">
    Require all granted
    </Files>

    اگر پوشه را با Directory Privacy رمزگذاری کرده‌اید، روی آپاچی ۲.۲ معادل این استثنا Satisfy Any به همراه Allow from all است.

۷. سطح دسترسی فایل‌ها و پوشه آپلود

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

فایل پیکربندی حساس‌ترین فایل سایت است، چون نام کاربری و رمز دیتابیس داخل آن قرار دارد. نام این فایل در جوملا configuration.php و در وردپرس wp-config.php است. سطح دسترسی آن را فقط‌خواندنی کنید (دستور را در ریشه همان سایت اجرا کنید):

chmod 400 wp-config.php

یک نکته عملی: مقدار 400 وقتی کار می‌کند که PHP با همان کاربری اجرا شود که مالک فایل است؛ این حالت روی هاست‌های اشتراکی cPanel و دایرکت‌ادمین رایج است. اگر بعد از این تغییر سایت خطای دسترسی داد، 440 یا 640 را امتحان کنید. در جوملا یک نکته اضافه هست: ذخیره «تنظیمات کلی» در پیشخوان، فایل configuration.php را بازنویسی می‌کند، پس تا وقتی سطح دسترسی ۴۰۰ است ذخیره تنظیمات خطا می‌دهد؛ موقع تغییر تنظیمات آن را موقتاً 644 کنید و بعد برگردانید. در وردپرس هم افزودن خط define('DISALLOW_FILE_EDIT', true); به فایل پیکربندی، ویرایشگر داخلی قالب و افزونه را غیرفعال می‌کند و یک مسیر رایج برای کاشتن کد مخرب را می‌بندد.

اجرای PHP را در پوشه آپلود ببندید

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

در وردپرس فایل .htaccess با محتوای زیر را در wp-content/uploads/ و در جوملا در images/ بسازید (آپاچی ۲.۴). پیشوند (?i) عمداً آنجاست تا فایلی با پسوند بزرگ مثل shell.PHP هم از قلم نیفتد:

<FilesMatch "(?i).(php|phtml|phps|php[0-9]|phar)$">
Require all denied
</FilesMatch>

معادل منسوخ همین قانون روی آپاچی ۲.۲:

# فقط برای Apache 2.2 — منسوخ است
<FilesMatch "(?i).(php|phtml|phps|php[0-9]|phar)$">
Order Deny,Allow
Deny from all
</FilesMatch>

و روی nginx، در کانفیگ سایت. اینجا هم یک نکته ترتیبی هست: nginx بلوک‌های regex را به ترتیبی که نوشته شده‌اند بررسی می‌کند و اولین تطبیق برنده است، پس این بلوک باید بالاتر از بلوک عمومی location ~ .php$ نوشته شود، وگرنه بی‌اثر است در حالی که شما فکر می‌کنید محافظت برقرار است:

# باید پیش از بلوک عمومی php نوشته شود
location ~* ^/wp-content/uploads/.*.php$ {
    deny all;
}

# معادل جوملا:
location ~* ^/images/.*.php$ {
    deny all;
}

باز هم بعد از تغییر، nginx -t و سپس reload. اگر روی هاست اشتراکی هستید و .htaccess اثر نکرد، از پشتیبانی بخواهید این محدودیت را در سطح سرور برایتان اعمال کند.

۸. یک لایه فایروال و پایش در سطح سرور

افزونه‌های امنیتی وردپرس و جوملا می‌توانند تلاش‌های ورود مشکوک را ببندند و تغییر فایل‌ها را گزارش کنند، اما هیچ‌کدام جایگزین به‌روزرسانی نیستند؛ افزونه امنیتی روی سایتی که افزونه‌های قدیمی دارد فقط حس امنیت می‌سازد. ترکیب مؤثرتر، محافظت در سطح سرور در کنار بهداشت نرم‌افزاری در سطح سایت است. روی هاست اشتراکی این لایه بر عهده ارائه‌دهنده است، پس پیش از خرید بپرسید در سطح سرور چه چیزی اجرا می‌شود. برای نمونه هاست وردپرس ایران روی کنترل‌پنل cPanel ارائه می‌شود و از CloudLinux برای مدیریت منابع و جلوگیری از اثرگذاری مصرف بالای دیگر کاربران بر عملکرد سایت شما استفاده می‌کند؛ انتقال سایت وردپرسی از هاست قبلی هم توسط تیم فنی انجام می‌شود.

۹. اگر گمان می‌کنید سایت هک شده

نشانه‌های رایج آلودگی: ریدایرکت شدن بازدیدکننده به سایت ناشناس (اغلب فقط برای کاربر موبایل یا فقط وقتی از گوگل وارد می‌شود)، ظاهر شدن صفحه‌های اسپم در نتایج جست‌وجو، هشدار قرمز مرورگر، ارسال ناگهانی حجم بالای ایمیل از هاست، و کاربر مدیری که خودتان نساخته‌اید. برای بررسی سه کار را پشت سر هم انجام دهید.

الف) اسکن از بیرون

سرویس‌های اسکن آنلاین مثل SiteCheck شرکت Sucuri صفحه‌های سایت را از بیرون می‌خوانند و کد تزریق‌شده، ریدایرکت مخرب و قرار گرفتن دامنه در فهرست‌های سیاه را گزارش می‌کنند. برای بررسی فهرست سیاه، اسکن آدرس سایت در VirusTotal و بخش Security Issues در سرچ کنسول گوگل هم مکمل خوبی است. اگر افزونه اسکن بدافزار روی خود سایت نصب می‌کنید، سراغ نام‌های شناخته‌شده بروید و بدانید نسخه‌های پولی‌شان معمولاً امکانات پاک‌سازی بیشتری دارند.

این کار سریع است و به هیچ دسترسی‌ای نیاز ندارد، اما محدودیت مهمی دارد: اسکنر بیرونی فقط چیزی را می‌بیند که در خروجی صفحه دیده می‌شود. یک backdoor خاموش که منتظر درخواست خاصی است، از بیرون نامرئی است. پس «تمیز» بودن گزارش اسکنر بیرونی به‌تنهایی به معنای سالم بودن سایت نیست.

ب) اسکن روی خود سرور

اسکن سمت سرور فایل‌های واقعی را می‌خواند و همان چیزی است که شل‌ها و backdoorها را پیدا می‌کند. روی سرورهای cPanel و دایرکت‌ادمین معمولاً از CXS استفاده می‌شود؛ این ابزار تجاری است و با دسترسی root اجرا می‌شود، یعنی روی هاست اشتراکی کار شماست که از پشتیبانی درخواست اسکن و گزارش آن را بدهید، نه اینکه خودتان اجرایش کنید. اگر سرور مجازی یا اختصاصی خودتان را دارید، ابزارهای رایگانی مثل ClamAV و maldet هم همین نقش را در سطح ابتدایی‌تری بازی می‌کنند.

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

# cPanel
find /home/USER/public_html -type f -name "*.php" -mtime -7 -ls

# دایرکت‌ادمین
find /home/USER/domains/example.com/public_html -type f -name "*.php" -mtime -7 -ls

ج) لاگ‌ها را بخوانید

لاگ‌ها به شما می‌گویند نفوذ از کجا انجام شده و بدون آن پاک‌سازی فقط تکرار می‌شود. لاگ ورود به کنترل‌پنل و FTP را بررسی کنید؛ روی سرورهای cPanel تلاش‌های ورود موفق و ناموفق به کنترل‌پنل در /usr/local/cpanel/logs/login_log ثبت می‌شود و ریز درخواست‌ها در /usr/local/cpanel/logs/access_log است. لاگ انتقال فایل FTP هم معمولاً /var/log/xferlog است. اگر دسترسی SSH دارید، ورودهای موفق و ناموفق سیستم را هم ببینید:

last                 # ورودهای موفق
lastb                # ورودهای ناموفق (نیازمند دسترسی root)

# AlmaLinux / Rocky / CentOS
tail -n 200 /var/log/secure

# Ubuntu / Debian
tail -n 200 /var/log/auth.log

# روی توزیع‌های جدیدی که دیگر فایل wtmp/btmp یا auth.log ندارند:
journalctl -t sshd -n 200

روی هاست اشتراکی به این فایل‌ها دسترسی ندارید؛ همان درخواست را به پشتیبانی بدهید.

د) بعد از پاک‌سازی

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

  • رمز همه حساب‌ها را عوض کنید: کنترل‌پنل، FTP، SSH، کاربر دیتابیس و همه کاربران مدیر سایت.
  • کاربران مدیری که نمی‌شناسید حذف کنید.
  • در وردپرس کلیدهای امنیتی (salts) داخل wp-config.php را با مقادیر جدید جایگزین کنید تا نشست‌های باز فعلی — از جمله نشست مهاجم — باطل شوند.
  • هسته، قالب و همه افزونه‌ها را به آخرین نسخه ببرید و هر قالب یا افزونه‌ای که از منبع نامطمئن آمده حذف کنید.

۱۰. پشتیبان‌گیری، اما پشتیبانی که تست شده باشد

پشتیبان تنها راهکاری است که حتی وقتی همه لایه‌های دیگر شکست خوردند کار می‌کند. سه نکته را رعایت کنید: پشتیبان‌ها باید خودکار و زمان‌بندی‌شده باشند (برای نمونه زمان‌بندی بکاپ و ریستور در پلسک)، دست‌کم یک نسخه باید بیرون از همان سرور نگهداری شود (پشتیبانی که کنار سایت هک‌شده است هم آلوده می‌شود)، و مهم‌تر از همه، حداقل یک بار بازگردانی را واقعاً تمرین کنید؛ پشتیبانی که هرگز بازگردانده نشده فقط یک فرض است.

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

۱۱. وضعیت سایت را دوره‌ای بررسی کنید

خیلی از مشکلات با یک بررسی ساده بیرونی پیدا می‌شوند: گواهی SSL منقضی‌شده، ریدایرکت HTTP به HTTPS که کار نمی‌کند، یا رکورد DNS جامانده. سرویس رایگان بررسی سلامت سایت بدون نیاز به ثبت‌نام، وضعیت گواهی SSL، رکوردهای DNS، در دسترس بودن سایت از داخل ایران و خارج، مشخصات میزبانی و وب‌سرور، سرعت بارگذاری و خطاهای کنسول و شبکه را گزارش می‌دهد.

جمع‌بندی

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