# امنیت وردپرس؛ ۲۰ اقدام عملی از هاست تا افزونه برای جلوگیری از هک

> امنیت وردپرس با ۲۰ اقدام عملی: به‌روزرسانی، ورود دومرحله‌ای، wp-config.php، بستن PHP در uploads، بکاپ، افزونهٔ امنیتی و پاک‌سازی سایت هک‌شده.

- صفحه: https://hakanserver.com/wordpress-security/
- تاریخ انتشار: ۸ آبان ۱۴۰۵ (2026-10-30)
- دسته: میزبانی وب
- زمان مطالعه: حدود 22 دقیقه

![سپر و قفل کنار سرور با نشان وردپرس و علامت هشدار؛ راهنمای امنیت وردپرس و جلوگیری از هک](https://hakanserver.com/wp-content/uploads/2026/10/wordpress-security.jpg)

امنیت وردپرس بیشتر از هر افزونه‌ای به چند عادت ساده بستگی دارد: کدهای به‌روز، ورود امن مدیران و بکاپی که بیرون از هاست نگه داشته می‌شود. در این راهنما ۲۰ اقدام عملی را به ترتیب اثر، هر کدام با مراحل دقیق و روش بررسی، و پاک‌سازی قدم‌به‌قدم سایت هک‌شده می‌خوانید.

بیشتر حمله‌ها کار ربات‌هایی است که خودکار دنبال افزونهٔ آسیب‌پذیر و رمز ضعیف می‌گردند. طبق [گزارش سالانهٔ Patchstack](https://patchstack.com/whitepaper/state-of-wordpress-security-in-2026/)، از ۱۱٬۳۳۴ آسیب‌پذیری تازهٔ سال ۲۰۲۵، ۹۱٪ در افزونه‌ها و ۹٪ در پوسته‌ها بود و فقط ۶ مورد در هستهٔ وردپرس. مسیر منوها مطابق پیشخوان فارسی وردپرس 7.1 است، آخرین نسخه در زمان نگارش این مطلب (آبان ۱۴۰۵).

> **به‌طور خلاصه:** برای یک وبلاگ یا سایت شرکتی کوچک، این شش کار بیشترین اثر را دارند:
> 
> 
> 
> 1. هسته، افزونه‌ها و پوسته‌ها را به‌روز نگه دارید و هر چه استفاده نمی‌کنید، حذف کنید.
> 2. قالب یا افزونهٔ نال‌شده نصب نکنید.
> 3. برای هر مدیر رمز یکتا و ورود دومرحله‌ای بگذارید.
> 4. سایت را کامل روی HTTPS ببرید و `DISALLOW_FILE_EDIT` را در `wp-config.php` بگذارید.
> 5. هر روز بکاپ بگیرید و یک نسخه را بیرون از هاست نگه دارید.
> 6. فقط یک افزونهٔ امنیتی نصب و تنظیم کنید.
> 
> 
> فروشگاه‌ها و سایت‌های پربازدید بقیهٔ فهرست را هم اجرا کنند.

## به‌روزرسانی هسته، افزونه‌ها و پوسته‌ها

### ۱. به‌روزرسانی خودکار هسته را خاموش نکنید

وردپرس نسخه‌های جزئی (مثل 7.1.3 به 7.1.4) را که برای رفع اشکال و وصلهٔ امنیتی منتشر می‌شوند، خودکار نصب می‌کند و از وردپرس 5.6، در نصب‌های تازه نسخه‌های اصلی را هم. اگر در `wp-config.php` ثابت `AUTOMATIC_UPDATER_DISABLED` یا `DISALLOW_FILE_MODS` با مقدار `true`، یا `WP_AUTO_UPDATE_CORE` با مقدار `false` هست، وصله‌های امنیتی هم نصب نمی‌شوند؛ اگر عمدی نیست، حذفش کنید. روی هاست داخل ایران، در اختلال اینترنت بین‌الملل ممکن است به‌روزرسانی انجام نشود؛ بعد از وصل شدن، دستی بررسی کنید.

**بررسی:** در پیشخوان › به‌روزرسانی‌ها نباید پیام «این سایت به‌روزرسانی خودکار نگارش‌های جدید وردپرس را دریافت نخواهد کرد.» را ببینید.

### ۲. افزونه‌ها و پوسته‌ها را مرتب به‌روز کنید

طبق همان گزارش، مهاجمان حدود نیمی از آسیب‌پذیری‌های پرخطر را در ۲۴ ساعت اول بعد از انتشار به کار گرفته‌اند؛ پس به‌روزرسانی ماهانه دیر است. در افزونه‌ها › افزونه‌های نصب‌شده، لینک «فعال‌سازی به‌روزرسانی‌های خودکار» را برای افزونه‌های ساده‌ای مثل فرم تماس و سئو بزنید (برای پوسته‌ها، در نمایش › پوسته‌ها روی تصویر پوسته کلیک کنید)؛ وردپرس روزی دو بار به‌روزرسانی‌ها را بررسی و نصب می‌کند و نتیجه را ایمیل می‌کند. ووکامرس و درگاه پرداخت را بعد از بکاپ، دستی به‌روز کنید (هفته‌ای یک بار و وصلهٔ امنیتی را همان روز) و یک سفارش آزمایشی بگیرید.

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

```
wp plugin list --fields=name,version,update,wporg_last_updated
```

**بررسی:** در پیشخوان › به‌روزرسانی‌ها نباید موردی در انتظار مانده باشد؛ اگر به‌روزرسانی خودکار انجام نمی‌شود، هشدارهای ابزارها › سلامت سایت را ببینید.

### ۳. افزونه و پوستهٔ بلااستفاده را حذف کنید

فایل‌های افزونهٔ غیرفعال روی هاست می‌مانند و اگر آسیب‌پذیر باشند، ممکن است مستقیم از مرورگر اجرا شوند؛ پس افزونهٔ بی‌استفاده را غیرفعال و بعد «حذف» کنید. از پوسته‌ها فقط پوستهٔ فعال، پوستهٔ والدش (اگر پوستهٔ فرزند دارید) و یک پوستهٔ پیش‌فرض وردپرس برای عیب‌یابی بماند.

**بررسی:** در فهرست افزونه‌ها، فیلتر «غیر فعال» دیگر نباید دیده شود.

### ۴. قالب و افزونهٔ نال‌شده نصب نکنید

نسخهٔ نال‌شده (Nulled) نسخهٔ پولی‌ای است که بررسی لایسنس از کدش حذف شده و در سایت‌های دانلود رایگان پخش می‌شود؛ کسی که کد را دستکاری کرده، می‌تواند هر چیز دیگری هم به آن اضافه کند. بدافزار WP-VCD که Wordfence در سال ۲۰۱۹ گزارش کرد، از همین راه پخش شد و به سایت‌های دیگر همان هاست هم سرایت می‌کرد. اگر خرید نسخهٔ اصلی ممکن نیست، جایگزین رایگانی از [مخزن رسمی افزونه‌های وردپرس](https://wordpress.org/plugins/) بگیرید و قالبی را که از سایت دانلود رایگان گرفته‌اید، آلوده فرض کنید.

## حساب‌های کاربری و دسترسی‌ها

### ۵. برای هر حساب رمز یکتا و بلند بگذارید

رمز تکراری از رمز کوتاه هم خطرناک‌تر است: رمزی که در سایت دیگری لو رفته، روی صفحهٔ ورود شما هم امتحان می‌شود. رمز وردپرس، cPanel، FTP، دیتابیس و ایمیل بازیابی هر کدام باید جدا، تصادفی و دست‌کم ۱۶ نویسه‌ای باشد؛ دکمهٔ «تنظیم رمز عبور جدید» در کاربران › شناسنامه چنین رمزی می‌سازد. رمزها را در مدیر رمز عبوری مثل KeePassXC (آفلاین) نگه دارید.

**بررسی:** در مدیر رمز، هیچ دو حسابی نباید رمز یکسان داشته باشند.

### ۶. ورود دومرحله‌ای را برای مدیران فعال کنید

با ورود دومرحله‌ای (2FA)، رمز دزدیده‌شده بدون کد شش‌رقمی اپلیکیشن گوشی به کار نمی‌آید. وردپرس 2FA داخلی ندارد؛ اگر افزونهٔ امنیتی‌تان آن را دارد (Wordfence، AIOS و Kadence Security در نسخهٔ رایگان)، از همان استفاده کنید، وگرنه افزونهٔ سبک [Two Factor](https://wordpress.org/plugins/two-factor/) از مشارکت‌کنندگان وردپرس کافی است:

1. در کاربران › شناسنامه، بخش «گزینه‌های دو عاملی» (Two-Factor Options)، «نرم‌افزار تأیید هویت» را فعال و کد QR را با اپلیکیشنی مثل Google Authenticator اسکن کنید.
2. «کدهای بازیابی» (Recovery Codes) را هم فعال کنید و کدها را جدا از گوشی نگه دارید.
3. از همهٔ مدیران و ویرایشگرها بخواهید همین کار را بکنند. روش ایمیلی را روش اصلی نکنید؛ اگر ایمیل سایت نرسد، به پیشخوان راه ندارید.

**بررسی:** از پنجرهٔ ناشناس مرورگر وارد شوید؛ بعد از رمز باید کد دومرحله‌ای خواسته شود.

### ۷. کاربر admin و مدیران اضافه را حذف کنید

نام کاربری راز نیست، اما `admin` اولین حدس ربات‌هاست؛ اگر نام کاربری‌تان این است، مدیر تازه‌ای بسازید و کاربر قدیمی را با گزینهٔ «همهٔ محتوا را به کاربر دیگری نسبت دهید.» حذف کنید. مهم‌تر از نام، تعداد مدیران است؛ هر نفر فقط نقشی را بگیرد که لازم دارد:

| نقش | دسترسی | برای |
| --- | --- | --- |
| مدیر کل | همه‌چیز، از جمله افزونه‌ها و کاربران | صاحب سایت و یک نفر فنی |
| ویرایشگر | همهٔ نوشته‌ها، حتی درج جاوااسکریپت بدون فیلتر | سردبیر مورد اعتماد |
| نویسنده | انتشار نوشته‌های خودش | نویسندهٔ ثابت |
| مشارکت‌کننده | نوشتن بدون انتشار | مهمان و فریلنسر |

فهرست مدیران را هر چند ماه مرور کنید:

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

**بررسی:** در تنظیمات › عمومی، «نقش پیش‌فرض کاربر تازه» باید «مشترک» باشد و اگر ثبت‌نام عمومی لازم ندارید، «هر کسی می‌تواند نام‌نویسی کند» تیک نخورده باشد.

### ۸. رمزهای عبور برنامه را بازبینی کنید

رمز عبور برنامه (Application Password) برای اتصال اپلیکیشن‌ها و سرویس‌های خودکارسازی از راه REST API و XML-RPC است؛ با آن نمی‌شود وارد پیشخوان شد، اما دسترسی همان کاربر را دارد و ورود دومرحله‌ای، مثلاً در افزونهٔ Two Factor، عمداً جلویش را نمی‌گیرد. در شناسنامهٔ هر مدیر، بخش «رمزهای عبور برنامه» را با ستون‌های «آخرین استفاده» و «آخرین IP» ببینید و رمز ناشناس را «ابطال» کنید. اگر هیچ سرویسی لازمش ندارد، با این فایل در `wp-content/mu-plugins` (پوشه را اگر نیست بسازید) خاموشش کنید؛ Wordfence این کار را به‌طور پیش‌فرض می‌کند:

```

  
    Require all denied
  
  
    Order allow,deny
    Deny from all
  

```

در Nginx:

```
location = /xmlrpc.php {
    deny all;
}
```

**بررسی:** `https://example.com/xmlrpc.php` پیش از بستن پیام `XML-RPC server accepts POST requests only.` و بعد از آن خطای 403 می‌دهد. اگر Jetpack قطع شد، قاعده را بردارید یا طبق [راهنمای Jetpack](https://jetpack.com/support/how-to-add-jetpack-ips-allowlist/) فقط IPهای آن را مجاز کنید.

## HTTPS و تنظیمات wp-config.php

### ۱۱. کل سایت را روی HTTPS ببرید

بدون HTTPS، رمز و کوکی ورود روی وای‌فای عمومی یا هر جای مسیر قابل شنود است. گواهی رایگان Let’s Encrypt یا AutoSSL در cPanel برای بیشتر سایت‌ها کافی است؛ تفاوت گواهی رایگان و پولی را در [SSL چیست؟](https://hakanserver.com/what-is-ssl/) ببینید و اگر گواهی پولی لازم دارید، صفحهٔ [خرید SSL](https://hakanserver.com/buy-ssl/) را. بعد از نصب گواهی، در تنظیمات › عمومی «نشانی وردپرس (URL)» و «نشانی سایت (URL)» را با `https://` ذخیره کنید، در cPanel › Domains کلید Force HTTPS Redirect را روشن کنید و `FORCE_SSL_ADMIN` را طبق اقدام بعد اضافه کنید.

**بررسی:** `http://example.com/wp-login.php` باید خودکار به `https` برود و مرورگر هشدار محتوای ناامن (Mixed Content) ندهد.

### ۱۲. ویرایشگر فایل پیشخوان را خاموش کنید

«ویرایشگر پرونده پوسته» و «ویرایشگر پرونده افزونه» اجازه می‌دهند کد PHP را از داخل پیشخوان ویرایش کنید؛ اگر رمز یک مدیر لو برود، ساده‌ترین راه کاشتن در پشتی (Backdoor) همین است. یک نسخه از `wp-config.php` (در پوشهٔ اصلی سایت) دانلود کنید و این دو خط را بالای خطی بگذارید که با `/* That's all, stop editing!` شروع می‌شود:

```
define( 'DISALLOW_FILE_EDIT', true );
define( 'FORCE_SSL_ADMIN', true );
```

خط دوم را فقط وقتی بگذارید که HTTPS سایت کار می‌کند، وگرنه به پیشخوان راه ندارید. ثابت اول را با `DISALLOW_FILE_MODS` اشتباه نگیرید که به‌روزرسانی‌ها را هم می‌بندد. `WP_DEBUG` را هم روی سایت اصلی روشن نگذارید؛ لاگ پیش‌فرضش در `wp-content/debug.log` از مرورگر قابل دانلود است.

**بررسی:** منوهای ویرایشگر پرونده باید حذف شده باشند. اگر صفحهٔ سفید یا خطای 500 دیدید، نقطه‌ویرگول یا نقل‌قولی جا افتاده است؛ نسخهٔ قبلی را برگردانید (راه‌های بیشتر در [حل مشکل صفحه سفید وردپرس](https://hakanserver.com/fix-wordpress-white-screen-issue/)).

### ۱۳. کلیدهای امنیتی را تازه کنید

هشت ثابت `AUTH_KEY` تا `NONCE_SALT` در `wp-config.php` کوکی‌های ورود را امضا می‌کنند. اگر هنوز `put your unique phrase here` دارند یا احتمال لو رفتن فایل هست، هشت خط تازه را از [سرویس رسمی کلیدهای وردپرس](https://api.wordpress.org/secret-key/1.1/salt/) جایگزین کنید یا `wp config shuffle-salts` را بزنید. این کار همهٔ کوکی‌ها را باطل می‌کند و همه، از جمله مهاجمی که کوکی دزدیده، باید دوباره وارد شوند.

**بررسی:** با بارگذاری دوبارهٔ پیشخوان باید به صفحهٔ ورود بروید.

### ۱۴. مجوز فایل‌ها و wp-config.php را درست کنید

طبق [مستندات وردپرس دربارهٔ مجوز فایل‌ها](https://developer.wordpress.org/advanced-administration/server/file-permissions/)، پوشه‌ها 755، فایل‌ها 644 و `wp-config.php` سخت‌گیرانه‌تر، 400 یا 440 باشد؛ 777 را هرگز، حتی برای uploads، ندهید. از Terminal یا SSH در cPanel (یا با گزینهٔ Permissions در File Manager):

```
cd ~/public_html
find . -type d -exec chmod 755 {} \;
find . -type f -exec chmod 644 {} \;
chmod 400 wp-config.php
ls -l wp-config.php
```

اگر بعد از 400 خطای 500 دیدید، PHP با کاربری غیر از مالک فایل اجرا می‌شود؛ به 644 برگردید و از پشتیبانی هاست بپرسید. برای ویرایش بعدی این فایل، مجوز را موقتاً 600 کنید و بعد به 400 برگردانید.

**بررسی:** خروجی `ls` باید با `-r--------` شروع شود و سایت عادی باز شود.

## امنیت در سطح هاست و سرور

قاعده‌های `.htaccess` این بخش برای Apache و LiteSpeed است؛ OpenLiteSpeed از `.htaccess` فقط قاعده‌های بازنویسی را می‌خواند. همهٔ سایت‌های یک حساب cPanel با یک کاربر لینوکس اجرا می‌شوند و آلودگی یکی می‌تواند به بقیه هم برسد؛ سایت‌های آزمایشی و رهاشده را حذف یا جدا کنید. از ارائه‌دهنده هم بپرسید فایروال وب (WAF) سمت سرور، مثل ModSecurity، فعال است یا نه.

### ۱۵. از نسخهٔ پشتیبانی‌شدهٔ PHP استفاده کنید

وردپرس PHP 8.3 یا جدیدتر را توصیه می‌کند. در زمان نگارش این مطلب (آبان ۱۴۰۵) شاخه‌های 8.2 تا 8.5 وصلهٔ امنیتی می‌گیرند و پشتیبانی 8.2 در ۱۰ دی ۱۴۰۵ (۳۱ دسامبر ۲۰۲۶) تمام می‌شود. نسخهٔ فعلی را در ابزارها › سلامت سایت › اطلاعات، بخش «سرور» ببینید و در cPanel با MultiPHP Manager (یا Select PHP Version در هاست‌های CloudLinux) عوض کنید؛ پیش از آن بکاپ بگیرید و بعد از آن صفحه‌های اصلی و پرداخت را آزمایش کنید.

**بررسی:** سلامت سایت نباید هشدار نگارش منسوخ PHP بدهد.

### ۱۶. اجرای PHP را در پوشهٔ uploads ببندید

در `wp-content/uploads` فقط باید عکس و فایل باشد. اگر افزونه‌ای آسیب‌پذیر آپلود فایل PHP را ممکن کند، مهاجم با باز کردن آن در مرورگر کد خودش را اجرا می‌کند. در Apache یا LiteSpeed این بلوک را در `.htaccess` داخل خود `wp-content/uploads` بگذارید (اگر فایل هست، به انتهایش اضافه کنید). این قاعده با هر ترکیب حروف کوچک و بزرگ، پسوندهای `.php8` و `.phtml` را هم که هندلر MultiPHP در cPanel به PHP می‌سپارد و نام‌هایی مثل `shell.php.jpg` را که Apache با `AddHandler` ممکن است اجرا کند، می‌بندد:

```

  
    Require all denied
  
  
    Order allow,deny
    Deny from all
  

```

در Nginx این بلوک از مستندات وردپرس را داخل `server {}` و **پیش از** `location ~ \.php$` بگذارید، چون Nginx قاعده‌های regex را به ترتیب بررسی می‌کند و اولین تطبیق برنده است:

```
location ~* /(?:uploads|files)/.*\.php$ {
    deny all;
}
```

**بررسی:** یک فایل آزمایشی بسازید، از بیرون صدا بزنید و پاکش کنید. پاسخ باید `403` باشد؛ `200` یعنی قاعده اعمال نشده و باید از ارائه‌دهنده کمک بخواهید:

```
cd ~/public_html
echo ' wp-content/uploads/test-php.php
curl -s -o /dev/null -w "%{http_code}\n" https://example.com/wp-content/uploads/test-php.php
rm wp-content/uploads/test-php.php
```

### ۱۷. فهرست پوشه‌ها و فایل‌های حساس را ببندید

با روشن بودن نمایش فهرست پوشه، هر کسی با باز کردن `/wp-content/uploads/` همهٔ فایل‌ها را می‌بیند. این خط‌ها را به `.htaccess` اصلی، بیرون از بلوک `# BEGIN WordPress` تا `# END WordPress` اضافه کنید؛ بخش دوم، قاعدهٔ [صفحهٔ Hardening مستندات وردپرس](https://developer.wordpress.org/advanced-administration/security/hardening/) برای بستن دسترسی مستقیم به `wp-config.php` است:

```
Options -Indexes

  
    Require all denied
  
  
    Order allow,deny
    Deny from all
  

```

در cPanel می‌توانید فهرست پوشه را بدون ویرایش فایل هم از Advanced › Indexes با گزینهٔ No Indexing ببندید (در Nginx به‌طور پیش‌فرض خاموش است). اگر بعد از ذخیره خطای 500 گرفتید، هاست تغییر `Options` را اجازه نمی‌دهد؛ خط اول را بردارید و از پشتیبانی بخواهید. فایل بکاپ (`.zip` و `.sql`) را هم هرگز در `public_html` نگذارید.

**بررسی:** `https://example.com/wp-content/uploads/` باید خطای 403 بدهد، نه فهرست فایل‌ها.

## بکاپ، افزونهٔ امنیتی و پایش

### ۱۸. هر روز بکاپ بگیرید و نسخه‌ای بیرون از هاست نگه دارید

هیچ اقدامی احتمال هک را صفر نمی‌کند؛ بکاپ است که حادثه را به یک بازگردانی چندساعته تبدیل می‌کند. از فایل‌ها و دیتابیس بکاپ بگیرید و نسخه‌ها را چند هفته نگه دارید، چون آلودگی معمولاً دیر کشف می‌شود. نسخهٔ رایگان UpdraftPlus بکاپ زمان‌بندی‌شده را به FTP، فضای سازگار با Amazon S3، Google Drive یا Dropbox می‌فرستد؛ برای مقصد، حسابی جدا با دسترسی فقط به پوشهٔ بکاپ بسازید. روی هاست داخل ایران، سرویس‌های ابری خارجی ممکن است در اختلال اینترنت بین‌الملل در دسترس نباشند؛ گاهی یک نسخه را روی کامپیوتر خودتان هم دانلود کنید.

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

### ۱۹. فقط یک افزونهٔ امنیتی نصب و تنظیم کنید

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

| افزونه | در نسخهٔ رایگان | نکته |
| --- | --- | --- |
| Wordfence Security | فایروال داخل وردپرس، اسکن بدافزار، محدودیت ورود، 2FA | قواعد فایروال و امضاها در نسخهٔ رایگان ۳۰ روز دیرتر می‌رسند |
| Kadence Security (نام قبلی: Solid Security و iThemes Security) | محدودیت ورود، 2FA، تشخیص تغییر فایل، بررسی آسیب‌پذیری‌ها | reCAPTCHA و ثبت فعالیت کاربران فقط در Pro |
| All-In-One Security (AIOS) | قفل ورود، 2FA، تشخیص تغییر فایل، قواعد فایروال | اسکن بدافزار فقط در نسخهٔ پولی |
| Sucuri Security | ثبت رویدادها، بررسی یکپارچگی فایل‌ها، اسکن از بیرون | محدودیت ورود و فایروال فقط با سرویس پولی |

برای بیشتر سایت‌ها یکی از سه افزونهٔ اول، با 2FA، محدودیت ورود و اسکن زمان‌بندی‌شده، کافی است؛ فایروال ابری (مثل Cloudflare) برای فروشگاه یا سایتی ارزش دارد که هدف حملهٔ مداوم است. سرویس‌های پولی شرکت‌های آمریکایی ممکن است به‌دلیل تحریم به کاربران ایرانی فروخته نشوند ([Sucuri این را صریحاً نوشته است](https://docs.sucuri.net/billing/do-you-sell-to-my-country/)) و بخش ابری افزونه‌ها هم ممکن است از سرور داخل ایران پاسخ نگیرد؛ بعد از نصب، یک اسکن کامل را آزمایش کنید.

### ۲۰. لاگ فعالیت، تغییر فایل‌ها و Search Console را پایش کنید

- **لاگ فعالیت:** اگر افزونهٔ امنیتی‌تان ثبت نمی‌کند چه کسی کی وارد شد یا چه افزونه‌ای نصب کرد، Simple History یا WP Activity Log را نصب کنید.
- **تغییر فایل‌ها:** هشدار تغییر فایل PHP بیرون از زمان به‌روزرسانی را جدی بگیرید.
- **Google Search Console:** سایت را ثبت کنید تا اگر گوگل محتوای هک‌شده یا بدافزار دید، ایمیل بگیرید؛ گزارش Security issues در بخش Security & Manual Actions است.

## پاک‌سازی سایت هک‌شدهٔ وردپرس

ترتیب مهم است: اول دسترسی مهاجم را می‌بندید، بعد کدها را با نسخهٔ سالم جایگزین می‌کنید و در پایان رمزهای وردپرس را عوض می‌کنید تا در پشتی جامانده رمز تازه را نبیند. دستورهای WP-CLI را در پوشهٔ سایت و با `--skip-plugins --skip-themes` اجرا کنید تا کد آلودهٔ افزونه‌ها و پوسته‌ها اجرا نشود (`wp-config.php` و mu-pluginها باز هم بارگذاری می‌شوند). اگر SSH ندارید یا پیام `wp: command not found` گرفتید، راه بدون خط فرمان هر گام را دنبال کنید.

### نشانه‌های هک شدن

- گوگل زیر نتیجهٔ سایت نوشته است This site may be hacked یا کروم صفحهٔ قرمز هشدار نشان می‌دهد؛ وضعیت را با [ابزار Safe Browsing site status](https://transparencyreport.google.com/safe-browsing/search) هم ببینید.
- جست‌وجوی `site:example.com` صفحه‌هایی با عنوان ژاپنی، دارویی یا قمار نشان می‌دهد که شما نساخته‌اید.
- کاربرانی که از گوگل یا با موبایل می‌آیند به سایت دیگری فرستاده می‌شوند، اما شما چیزی نمی‌بینید.
- مدیر یا افزونهٔ ناشناس یا فایل PHP در `uploads` پیدا شده، یا هاست به‌خاطر ارسال اسپم حساب را محدود کرده است.

### گام ۱: سایت را از دسترس عموم خارج کنید

در cPanel › Files › Directory Privacy، پوشهٔ `public_html` را انتخاب کنید، گزینهٔ Password protect this directory را بزنید، ذخیره کنید و یک کاربر بسازید تا بازدیدکننده‌ها و ربات‌ها پشت رمز بمانند. حالت تعمیر وردپرس (`wp maintenance-mode activate`) مناسب نیست، چون وردپرس آن را بعد از ۱۰ دقیقه نادیده می‌گیرد.

### گام ۲: یک نسخه نگه دارید و رمزهای هاست را عوض کنید

1. از فایل‌ها و دیتابیس، در همین وضعیت آلوده، بکاپی با نام روشن (مثلاً `infected-1405-08-08`) بیرون از هاست نگه دارید و برای پیدا کردن راه نفوذ، لاگ دسترسی وب‌سرور را هم از cPanel › Metrics › Raw Access بردارید.
2. رمز cPanel، حساب‌های FTP و ایمیل بازیابی را عوض کنید، حساب FTP ناشناس را حذف و در Security › SSH Access کلید ناشناس را پاک کنید.
3. در Advanced › Cron Jobs دنبال دستوری بگردید که خودتان نساخته‌اید؛ کرون‌جاب مخرب، بدافزار را دوباره نصب می‌کند.

### گام ۳: اگر بکاپ سالم دارید، از آن شروع کنید

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

### گام ۴: هسته را بررسی و با نسخهٔ سالم جایگزین کنید

```
cd ~/public_html
wp core verify-checksums
wp core download --version="$(wp core version)" --skip-content --force
wp core verify-checksums --include-root
```

دستور دوم بدون بارگذاری وردپرس، هسته را با چک‌سام رسمی مقایسه می‌کند: `File doesn't verify against checksum` یعنی فایل دستکاری شده و `File should not exist` یعنی فایل اضافه، که کنار پیام `Success` پایانی هم می‌آید؛ پس همهٔ خروجی را بخوانید. دستور سوم هستهٔ همان نسخه را از نو می‌نویسد و به `wp-config.php` و افزونه‌ها، پوسته‌ها و آپلودها دست نمی‌زند، اما فایل‌های اضافه را باید خودتان حذف کنید. `--include-root` پوشهٔ اصلی را هم می‌گردد؛ آنجا `robots.txt`، `.user.ini`، فایل فایروال افزونهٔ امنیتی و پوشهٔ سایت‌های دیگر طبیعی‌اند، اما فایل PHP ناآشنا مشکوک است.

بدون SSH، گزینهٔ Check WordPress Integrity در WP Toolkit (اگر هاست‌تان دارد) همین بررسی و نصب دوباره را انجام می‌دهد؛ وگرنه بستهٔ همان نسخه را از wordpress.org بگیرید، `wp-admin` و `wp-includes` را در File Manager حذف و از بسته دوباره آپلود کنید.

### گام ۵: افزونه‌ها و پوسته‌ها را از منبع رسمی دوباره نصب کنید

```
wp plugin verify-checksums --all --skip-plugins --skip-themes
```

در جدول خروجی، `Checksum does not match` یعنی فایل تغییر کرده و `File was added` یعنی فایل اضافه شده؛ افزونه‌های بیرون از مخزن پیام `Could not retrieve the checksums ... skipping` می‌گیرند. هر افزونهٔ مشکل‌دار را با نامش از ستون `plugin_name` به‌جای `SLUG` دوباره نصب کنید؛ `--force` پوشهٔ قبلی را پاک و نسخهٔ تازه را جایگزین می‌کند و تنظیمات در دیتابیس می‌ماند:

```
wp plugin install SLUG --force --skip-plugins --skip-themes
wp plugin verify-checksums SLUG --skip-plugins --skip-themes
```

- افزونه و پوستهٔ تجاری را از سازنده دوباره بگیرید. بدون SSH، پوشهٔ هر افزونه را در File Manager حذف و zip تازه‌اش را از wordpress.org آپلود کنید.
- پوسته‌های مخزن را با `wp theme install SLUG --force` دوباره نصب کنید؛ WP-CLI برای پوسته چک‌سام ندارد و فایل‌های پوستهٔ فرزند را باید خودتان بخوانید.
- برای نصب دوباره، افزونه را از پیشخوان «حذف» نکنید؛ ممکن است داده‌ها و تنظیماتش هم پاک شود.

### گام ۶: uploads، mu-plugins و فایل‌های پنهان را بگردید

```
find wp-content/uploads -type f \( -iname '*.php' -o -iname '*.php[0-9]' -o -iname '*.phtml' -o -iname '*.phar' -o -iname '*.php.*' \)
ls -la wp-content/mu-plugins
grep -rlE --include='*.php' 'eval[[:space:]]*\((base64_decode|gzinflate|gzuncompress|str_rot13)' wp-content
grep -rn --include='.htaccess' --include='.user.ini' --include='php.ini' 'auto_prepend_file' .
find . -name '.htaccess'
```

- در `uploads` نباید هیچ فایل PHP باشد؛ هر چه پیدا شد، حذف کنید (نسخه‌اش در بکاپ آلوده هست).
- فایل‌های `mu-plugins` خودکار اجرا می‌شوند و در پیشخوان فقط زیر فیلتر «لازم» دیده می‌شوند؛ فایل ناشناس را بررسی کنید.
- تطبیق دستور سوم الزاماً بدافزار نیست، اما کد مبهم‌شده بیرون از افزونه‌های رسمی بسیار مشکوک است.
- `auto_prepend_file` پیش از هر صفحه فایلی را اجرا می‌کند؛ جز فایل فایروال افزونهٔ امنیتی‌تان (مثل `wordfence-waf.php` یا `aios-bootstrap.php`)، مقدار ناشناس را بردارید و `.htaccess`ها را هم برای ریدایرکت ناشناس بخوانید.

### گام ۷: کاربران، تنظیمات و دیتابیس را بررسی کنید

```
wp user list --role=administrator --fields=ID,user_login,user_email,user_registered --skip-plugins --skip-themes
wp user application-password list ID --skip-plugins --skip-themes
wp option get admin_email --skip-plugins --skip-themes
wp option get users_can_register --skip-plugins --skip-themes
wp option get default_role --skip-plugins --skip-themes
wp db search '<script' --skip-plugins --skip-themes
```

- مدیر ناشناس را با `wp user delete ID --reassign=YOUR_ID` حذف کنید تا محتوایش به حساب شما برسد.
- رمز عبور برنامهٔ ناشناس هر مدیر را با `wp user application-password delete ID UUID` (یا همه را با `--all`) پاک کنید؛ عوض کردن رمز کاربر و کلیدهای امنیتی آن را باطل نمی‌کند.
- ایمیل مدیران و `admin_email` باید مال خودتان باشد؛ بازیابی رمز به ایمیل هر کاربر می‌رود.
- اگر ثبت‌نام لازم ندارید، `users_can_register` باید `0` باشد و `default_role` هرگز `administrator` نباشد.
- جست‌وجوی آخر، اسکریپت‌های داخل نوشته‌ها و تنظیمات را نشان می‌دهد و اسکریپتی که به دامنهٔ ناشناس می‌رود، مشکوک است؛ بدون SSH، جدول‌های `posts` و `options` را در phpMyAdmin بگردید.

### گام ۸: رمزها و کلیدها را عوض کنید و درخواست بررسی بدهید

1. رمز همهٔ مدیران و رمز کاربر دیتابیس را عوض کنید (cPanel › Manage My Databases، در نسخه‌های قدیمی MySQL Databases، بخش Current Users)، رمز تازه را در `DB_PASSWORD` بنویسید و `wp config shuffle-salts` را بزنید؛ اگر مجوز `wp-config.php` را 400 کرده‌اید، پیش از آن موقتاً 600 کنید.
2. اقدام‌های این راهنما، به‌ویژه ۱۶ و به‌روزرسانی همهٔ افزونه‌ها، را اجرا کنید تا راه نفوذ بسته شود؛ بعد Directory Privacy را بردارید.
3. در Search Console، وقتی همهٔ موارد گزارش Security issues در همهٔ صفحه‌ها رفع شد، Request Review را بزنید و بنویسید مشکل چه بود، چه کردید و نتیجه چه شد. طبق [مستندات گوگل](https://support.google.com/webmasters/answer/9044101) بررسی از چند روز تا چند هفته طول می‌کشد؛ تا نتیجه نیامده، درخواست تازه نفرستید.
4. تا چند هفته اسکن روزانه و لاگ فعالیت را دنبال کنید؛ برگشتن آلودگی یعنی در پشتی هنوز باقی است.

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

## رفع مشکلات رایج بعد از امن‌سازی

| نشانه | علت محتمل | راه‌حل |
| --- | --- | --- |
| `Error establishing a database connection` بعد از تغییر رمز دیتابیس | `DB_PASSWORD` در `wp-config.php` به‌روز نشده | رمز تازه را آنجا بنویسید |
| ریدایرکت بی‌پایان بعد از `FORCE_SSL_ADMIN` | Cloudflare با حالت Flexible؛ وردپرس HTTPS را نمی‌بیند | حالت Full (strict) با گواهی روی خود هاست |
| پشت ورود دومرحله‌ای یا CAPTCHA مانده‌اید | گوشی گم شده یا CAPTCHA بارگذاری نمی‌شود | کد بازیابی، یا تغییر نام پوشهٔ افزونه در File Manager |

## هاست مناسب برای سایت وردپرسی

برای یک سایت وردپرسی معمولی سرور مجازی لازم نیست؛ تقریباً همهٔ این اقدام‌ها روی هاست اشتراکی cPanel اجراشدنی است. [هاست لینوکس](https://hakanserver.com/buy-hosting-and-domain/linux-host/) هاکان سرور بر پایهٔ cPanel و با وب‌سرور LiteSpeed، در ایران و اروپا ارائه می‌شود. برای سایت وردپرسی، صفحه‌های [هاست وردپرس](https://hakanserver.com/wordpress-hosting/) و [پشتیبانی وردپرس](https://hakanserver.com/support-wordpress/) را هم ببینید. پشتیبانی فنی ۲۴ ساعته از طریق تیکت در دسترس است.

اگر وردپرس روی سرور مجازی است، امنیت خود سرور هم با شماست؛ برای آن، [۹ راهکار برای افزایش امنیت سرور لینوکس](https://hakanserver.com/%D8%A7%D9%81%D8%B2%D8%A7%DB%8C%D8%B4-%D8%A7%D9%85%D9%86%DB%8C%D8%AA-%D8%B3%D8%B1%D9%88%D8%B1-%D9%84%DB%8C%D9%86%D9%88%DA%A9%D8%B3/) را ببینید.

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

### آیا وردپرس امن است؟

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

### کدام افزونهٔ امنیتی وردپرس را نصب کنیم؟

یکی، نه چندتا. Wordfence، Kadence Security و AIOS در نسخهٔ رایگان محدودیت ورود، 2FA و بررسی تغییر فایل‌ها را دارند؛ هر کدام که روی هاست‌تان بدون خطا اسکن می‌کند، کافی است.

### تغییر پیشوند جدول‌های دیتابیس (wp_) لازم است؟

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

### هاست اشتراکی امن‌تر است یا سرور مجازی؟

به مدیریت بستگی دارد: در هاست اشتراکی امنیت سرور با ارائه‌دهنده است، اما در سرور مجازی سیستم‌عامل، وب‌سرور و فایروال هم با شماست. بدون تجربهٔ مدیریت سرور، هاست اشتراکی انتخاب امن‌تری است.

### اگر افزونهٔ نال‌شده را اسکن کنم و پاک باشد، می‌توانم استفاده کنم؟

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

## جمع‌بندی

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

قدم بعدی: امروز اقدام‌های ۱ تا ۷ را انجام دهید، این هفته بکاپ بیرونی و اقدام‌های ۱۲ و ۱۶ را اضافه کنید و پیش از پایان ماه، یک بازگردانی آزمایشی انجام دهید.

- مطلب قبلی: [SSL چیست؟ انواع گواهی SSL، تفاوت رایگان و پولی و راهنمای انتخاب](https://hakanserver.com/what-is-ssl/index.md)
- مطلب بعدی: [رفع خطای ERR_CONNECTION_TIMED_OUT در کروم؛ چک‌لیست کاربر و مدیر سرور](https://hakanserver.com/err-connection-timed-out/index.md)

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

- [حل مشکل صفحه سفید وردپرس](https://hakanserver.com/fix-wordpress-white-screen-issue/index.md)
- [چرا سایت من با خطای Error Establishing a Database Connection مواجه شده است؟](https://hakanserver.com/%D8%AE%D8%B7%D8%A7%DB%8C-error-establishing-a-database-connection/index.md)
- [هاست چیست؟ انواع هاست و راهنمای انتخاب هاست مناسب](https://hakanserver.com/%D9%87%D8%A7%D8%B3%D8%AA-%DA%86%DB%8C%D8%B3%D8%AA-%D9%88-%DA%86%D9%87-%D8%A7%D9%86%D9%88%D8%A7%D8%B9%DB%8C-%D8%AF%D8%A7%D8%B1%D8%AF%D8%9F/index.md)

## سرویس‌های مرتبط هاکان سرور

- [سرور مجازی](https://hakanserver.com/buy-a-virtual-server/index.md): ۵۲ لوکیشن در ایران و خارج
- [سرور اختصاصی](https://hakanserver.com/dedicatedserver/index.md): ایران و ۸ کشور دیگر
- [هاست و دامنه](https://hakanserver.com/buy-hosting-and-domain/index.md): هاست سی‌پنل ایران و اروپا

فهرست همهٔ مقاله‌ها: https://hakanserver.com/blog/index.md
فهرست همهٔ صفحه‌ها و راهنمای سایت: https://hakanserver.com/llms.txt
