جلوگیری از اجرای فایل های PHP در وردپرس

برای کاهش خطر سوءاستفاده از فایلهای مخرب در وردپرس، میتوان دسترسی مستقیم وب به فایلهای PHP در مسیرهایی مانند wp-content/uploads را محدود کرد.
در سرورهای Apache 2.4 و LiteSpeed سازگار با قواعد Apache، روش متداول این است که یک فایل .htaccess داخل پوشه uploads قرار دهید و درخواست مستقیم به پسوندهای اجرایی رایج را مسدود کنید. این تنظیم یک لایه دفاعی مفید است، اما بهتنهایی جلوی همه روشهای اجرای کد مخرب یا هکشدن سایت را نمیگیرد.
در این راهنما، ابتدا پوشه آپلودها را بهصورت محدود و قابلآزمایش امن میکنیم، سپس تفاوت آن با پوشه wp-includes و تنظیمات وبسرورهای مختلف را توضیح میدهیم. پیش از تغییر فایلهای سرور، از فایل تنظیمات فعلی نسخه پشتیبان بگیرید.
آنچه در این مقاله می خوانید :
چرا باید اجرای مستقیم PHP در پوشه آپلودها را محدود کرد؟
وردپرس فایلهای رسانهای مانند تصویر، ویدئو و سند را معمولاً در مسیر wp-content/uploads ذخیره میکند. این پوشه باید برای نمایش فایلهای مجاز از طریق وب قابلدسترسی باشد؛ بااینحال، قرار نیست فایل PHP بارگذاریشده در آن مانند یک اسکریپت سرور اجرا شود.
اگر مهاجم از یک آسیبپذیری، حساب کاربری بهخطرافتاده یا افزونهای ناامن برای قراردادن فایل اجرایی در پوشهای عمومی استفاده کند و وبسرور اجازه اجرای آن را بدهد، ممکن است بتواند آن فایل را مستقیماً از طریق URL فراخوانی کند. نتیجه احتمالی به مجوزهای سیستم، پیکربندی PHP و سطح دسترسی فرایند وبسرور بستگی دارد.
محدودکردن درخواست مستقیم به فایلهای اجرایی در پوشه آپلودها یک اقدام دفاعی تکمیلی است. بااینحال، این کار بهتنهایی فایل مخرب را حذف نمیکند و مانع اجرای کدی که از طریق یک اسکریپت آسیبپذیر دیگر فراخوانی میشود نخواهد شد. برای آشنایی با اقدامات مکمل، مقاله روشهای افزایش امنیت وردپرس را نیز ببینید.

تفاوت «مسدودکردن درخواست» و «غیرفعالکردن اجرای PHP»
قواعد .htaccess که در ادامه میآیند، درخواست HTTP مستقیم به فایلهایی با پسوندهای مشخص را رد میکنند. برای نمونه، اگر مرورگر بخواهد فایل example.php را از پوشه آپلودها دریافت کند، وبسرور باید دسترسی را مسدود کند.
این قاعده بهخودیخود مفسر PHP را در کل سایت غیرفعال نمیکند، فایل را از دیسک پاک نمیکند و تضمین نمیکند که برنامه دیگری نتواند آن فایل را با سازوکاری دیگر فراخوانی کند. همچنین اگر وبسرور بهصورت سفارشی پسوند دیگری را به PHP متصل کرده باشد، باید آن پسوند و تنظیم مربوط به آن جداگانه بررسی شود.
جلوگیری از اجرای مستقیم PHP در پوشه wp-content/uploads
اما برای جلوگیری از اجرای فایل های PHP در وردپرس، روش های مختلفی وجود دارد که در ادامه، ذکر شده است.
۱. از فایل تنظیمات و وضعیت فعلی سایت نسخه پشتیبان بگیرید
از فایل .htaccess ریشه وردپرس و هر فایل .htaccess موجود در پوشه آپلودها نسخه پشتیبان بگیرید. اگر امکان دارد، ابتدا روش را روی نسخه آزمایشی سایت امتحان کنید. در سایتهای حساس، تغییرات وبسرور را در زمان کمترافیک و با دسترسی آماده به File Manager یا SFTP انجام دهید.
۲. پوشه درست را در File Manager پیدا کنید
- وارد کنترلپنل هاست شوید و بخش File Manager را باز کنید.
- پوشه نصب وردپرس را پیدا کنید؛ در بسیاری از هاستها این مسیر
public_htmlاست، اما ممکن است نام یا محل آن متفاوت باشد. - به مسیر
wp-content/uploadsبروید. فایل تنظیمات باید مستقیماً داخلuploadsقرار بگیرد تا بر زیرپوشههای آن نیز اعمال شود. - اگر فایلهای نقطهدار نمایش داده نمیشوند، گزینهای مانند Show Hidden Files یا Show Hidden Files (dotfiles) را در تنظیمات File Manager فعال کنید.

۳. کد مناسب Apache 2.4 را داخل .htaccess پوشه uploads قرار دهید
یک فایل با نام دقیق .htaccess ایجاد کنید؛ دقت کنید پسوند اضافی مانند .txt نداشته باشد. سپس کد زیر را در آن قرار دهید:
<FilesMatch "(?i)\.(?:php[0-9]*|phtml|pht|phar)$">
Require all denied
</FilesMatch>
این قاعده در Apache 2.4 با فعالبودن ماژول کنترل دسترسی لازم و مجازبودن دستور در تنظیمات AllowOverride، درخواست مستقیم به فایلهایی با پسوندهایی مانند .php، .php8، .phtml، .pht و .phar را مسدود میکند. بخش (?i) تطبیق را نسبت به بزرگی و کوچکی حروف غیرحساس میکند؛ بنابراین شکلهایی مانند .PHP نیز در الگو قرار میگیرند.
فهرست پسوندها جایگزین بررسی تنظیمات واقعی سرور نیست. اگر ارائهدهنده هاست پسوندهای دیگری را برای اجرای PHP پیکربندی کرده باشد، باید قانون متناسب با همان پیکربندی را از مدیر سرور بگیرید. از اضافهکردن بیهدف پسوندهای عمومی مانند .jpg یا .txt خودداری کنید؛ مسدودسازی آنها میتواند نمایش رسانه یا فایلهای عادی را مختل کند.
در Apache 2.2 دستور Require all denied در دسترس نیست و روش کنترل دسترسی قدیمیتری به کار میرود. Apache 2.2 منسوخ شده است؛ اگر هنوز از آن استفاده میکنید، بهجای اتکا به کد جدید یا ترکیب چند سبک دستور در یک بلوک، از میزبان بخواهید نسخه و روش پشتیبانیشده را تأیید کند و برای ارتقا برنامهریزی کنید.
۴. فایل را ذخیره و در مسیر درست بارگذاری کنید
اگر فایل را در رایانه ساختهاید، آن را با نام دقیق .htaccess ذخیره و در مسیر wp-content/uploads/ بارگذاری کنید. اگر از File Manager استفاده میکنید، معمولاً میتوانید فایل را همانجا مستقیماً ایجاد و ویرایش کنید. اگر از قبل فایل .htaccess در این پوشه وجود دارد، آن را کورکورانه جایگزین نکنید؛ ابتدا محتوای فعلی را بررسی و پشتیبان تهیه کنید، سپس قاعده را با تنظیمات موجود ادغام کنید.
۵. نتیجه را بهشکل کنترلشده آزمایش کنید
- ابتدا یک تصویر یا فایل رسانهای سالم از پوشه آپلودها را در مرورگر باز کنید. باید مانند قبل در دسترس باشد.
- برای بررسی واقعی ردشدن درخواست PHP، بهترین گزینه اجرای آزمایش در محیط staging است. در آن محیط میتوان یک فایل آزمایشی بسیار ساده با نامی موقت ایجاد کرد، درخواست آن را بررسی کرد و بلافاصله فایل را حذف کرد.
- از باقیگذاشتن فایل آزمایشی PHP در سایت عمومی خودداری کنید. اگر محیط آزمایشی ندارید، پیش از ایجاد چنین فایلی از میزبان بخواهید اعمالشدن قانون را از روی پیکربندی و لاگ وبسرور بررسی کند.
- پاسخ
403 Forbiddenبرای درخواست فایل هدف معمولاً نشان میدهد دسترسی رد شده است؛ اما404 Not Foundبهتنهایی اثبات نمیکند قاعده کار میکند، چون ممکن است فایل وجود نداشته باشد.

آیا باید در پوشه wp-includes نیز همین قانون را قرار داد؟
خیر؛ wp-includes را نباید همانند پوشه آپلودها در نظر گرفت. این مسیر بخشی از هسته وردپرس است و علاوه بر فایلهای PHP، منابع و فایلهایی دارد که برای عملکرد سایت و برخی افزونهها استفاده میشوند. قراردادن قاعده عمومی منع دسترسی به تمام فایلهای PHP داخل آن ممکن است مسیرهای موردنیاز وردپرس یا افزونهها را از کار بیندازد.
راهنمای رسمی WordPress برای امنسازی wp-includes، بهجای مسدودکردن یکسان همه فایلهای PHP، مجموعهای از قواعد محدودتر mod_rewrite را پیشنهاد میکند که فایلها و مسیرهای مشخصی را که عموماً نباید مستقیماً فراخوانی شوند محدود میکند. برای نصب معمولی وردپرس در ریشه دامنه، این قواعد در فایل .htaccess ریشه نصب قرار میگیرند، نه در یک فایل جداگانه داخل wp-includes:
# Block the include-only files.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^wp-admin/includes/ - [F,L]
RewriteRule !^wp-includes/ - [S=3]
RewriteRule ^wp-includes/[^/]+\.php$ - [F,L]
RewriteRule ^wp-includes/js/tinymce/langs/.+\.php - [F,L]
RewriteRule ^wp-includes/theme-compat/ - [F,L]
</IfModule>
این قواعد را خارج از محدودههای # BEGIN WordPress و # END WordPress قرار دهید؛ وردپرس ممکن است محتوای داخل این محدوده را بازنویسی کند. نمونه بالا برای چیدمان متداولی است که وردپرس در ریشه دامنه نصب شده و به mod_rewrite دسترسی دارد. اگر وردپرس در زیرپوشه نصب شده یا فایل .htaccess ساختار سفارشی دارد، قواعد را بدون تطبیق مسیرها کپی نکنید.
هشدار مهم برای WordPress Multisite: مستندات رسمی وردپرس هشدار میدهد که قاعده
RewriteRule ^wp-includes/[^/]+\.php$ - [F,L]ممکن است در Multisite مانع کارکردms-files.phpبرای تحویل تصاویر شود. حذف این خط میتواند سازگاری را بهتر کند، اما بخشی از محدودسازی را نیز کاهش میدهد. در شبکههای چندسایته، پیش از اجرا ساختار شبکه و روش تحویل رسانهها را بررسی کنید.
تفاوت اجرای این تنظیم در Apache، LiteSpeed و Nginx
| وبسرور | روش معمول | نکته مهم |
|---|---|---|
| Apache 2.4 | استفاده از .htaccess و FilesMatch با Require all denied | باید ماژول و دستورهای لازم فعال باشند و AllowOverride اجازه استفاده از آنها را بدهد. |
| LiteSpeed Web Server | معمولاً استفاده از قواعد سازگار با Apache در .htaccess | LiteSpeed از قواعد .htaccess پشتیبانی میکند، اما بهدلیل تنظیمات میزبان یا قوانین بالادستی، نتیجه را عملاً آزمایش کنید. |
| Nginx | تنظیم قانون در پیکربندی سرور یا بلوک سایت | Nginx فایل .htaccess را مانند Apache نمیخواند؛ تغییر باید توسط مدیر سرور در پیکربندی Nginx انجام شود. |
نکتههای ویژه برای Apache و LiteSpeed
اگر قاعده اثری ندارد یا با خطای 500 Internal Server Error روبهرو شدید، ممکن است دستور در محیط فعلی مجاز نباشد، ماژول موردنیاز فعال نباشد، یا سینتکس فایل ایراد داشته باشد. تنظیم AllowOverride تعیین میکند کدام دستورها در فایلهای .htaccess مجازند؛ اگر میزبان این قابلیت را غیرفعال کرده باشد، فایل ممکن است نادیده گرفته شود یا بسته به دستورها خطا ایجاد شود. در چنین شرایطی از میزبان بخواهید قانون را در پیکربندی سطح سرور اعمال کند.
نمونه قاعده برای Nginx
نمونه زیر صرفاً الگوی راهنما برای قرارگرفتن در پیکربندی سایت Nginx است و نباید داخل فایل .htaccess قرار گیرد:
location ~* ^/wp-content/uploads/.*\.(php[0-9]*|phtml|pht|phar)$ {
deny all;
}
این بلوک باید پیش از بلوک عمومی پردازش PHP قرار گیرد تا درخواست فایلهای داخل uploads ابتدا با قانون منع دسترسی تطبیق پیدا کند. اگر نصب وردپرس در زیرمسیر است، مسیرها متفاوتاند یا پیکربندی Nginx قانونهای location پیچیدهای دارد، مدیر سرور باید ترتیب و الگوی نهایی را بررسی کند. پس از تغییر نیز پیش از بارگذاری مجدد سرویس، صحت پیکربندی با nginx -t بررسی شود.
اگر سایت خطای 403 یا 500 داد، چه کار کنیم؟
خطای 403 برای فایل یا مسیر مورد انتظار:
کد 403 برای فایل PHP که عمداً مسدود کردهاید معمولاً نتیجه مورد انتظار است. اما اگر تصاویر، فایلهای رسانهای یا عملکرد عادی سایت نیز با 403 مواجه شدند، ممکن است قاعده بیش از حد گسترده باشد یا یک قانون دیگر با آن تداخل داشته باشد. ابتدا فایل .htaccess را بررسی و هر تغییری را که درست پیش از بروز مشکل انجام شده است موقتاً به حالت قبلی برگردانید.
خطای 500 یا Internal Server Error
- از File Manager یا SFTP فایل
.htaccessتغییریافته را به نسخه پشتیبان برگردانید یا فقط قانون اضافهشده را موقتاً حذف کنید. - صفحه اصلی، ورود به مدیریت، نمایش رسانهها و چند مسیر مهم سایت را بررسی کنید.
- لاگ خطای وبسرور یا گزارش خطای ارائهدهنده هاست را بررسی کنید؛ خطا معمولاً مشخص میکند دستور ناشناخته، غیرمجاز یا دارای سینتکس نادرست بوده است.
- اگر وبسرور Nginx است، تغییر را در فایل
.htaccessانجام ندهید. اگر Apache یا LiteSpeed است ولی قواعد خوانده نمیشوند، از میزبان دربارهAllowOverrideو ماژولهای مجاز سؤال کنید.
پس از رفع علت، قاعده را در محیط آزمایشی بررسی کنید و تنها زمانی دوباره فعال کنید که دسترسی عادی سایت و فایلهای رسانهای سالم باشد.
اقدامهای تکمیلی برای امنسازی آپلودها
- آپلود را به کاربران مجاز محدود کنید: فقط نقشهایی که واقعاً به آپلود نیاز دارند امکان ارسال فایل داشته باشند. در فرمهای عمومی، نوع فایل، اندازه، نام و محتوای آن را سمت سرور اعتبارسنجی کنید.
- به پسوند فایل بهتنهایی اعتماد نکنید: بررسی نوع MIME نیز بهتنهایی کافی نیست، چون مقدار ارسالی کاربر قابل جعل است. کنترل نوع محتوا، پسوند مجاز و منطق پردازش باید با هم انجام شوند.
- مجوزها را محدود نگه دارید: از مجوز نوشتن غیرضروری برای فایلهای هسته، افزونهها و قالبها خودداری کنید. روش مناسب مالکیت و مجوزها به معماری هاست بستگی دارد؛ تغییر بازگشتی مجوزها بدون بررسی ممکن است به بهروزرسانی یا عملکرد سایت آسیب بزند.
- نرمافزار را بهروز نگه دارید: هسته وردپرس، افزونهها، قالبها و نسخه PHP را به نسخههای پشتیبانیشده و امن ارتقا دهید و افزونهها یا قالبهای بلااستفاده را حذف کنید.
- از فایلهای مهم محافظت کنید: نسخه پشتیبان سالم و قابلبازیابی تهیه کنید و پس از مشاهده فایل PHP ناشناس، فقط به بستن دسترسی اکتفا نکنید؛ مسیر نفوذ و سایر تغییرات احتمالی را نیز بررسی کنید. راهنمای بازگردانی سایت هکشده و مقاله بکدور چیست؟ در این زمینه مرتبطاند.
- پیکربندی وبسرور را در نظر بگیرید: در محیطهایی که مدیریت سرور در اختیار شماست، مدیر سرور میتواند اجرای PHP را در مسیر آپلودها در سطح پیکربندی سرور غیرفعال کند و امکان override شدن تنظیمات آن مسیر را محدود کند. این روش ممکن است از قاعده محلی
.htaccessمطمئنتر باشد، اما باید توسط فرد آشنا با پیکربندی سرور پیادهسازی شود.
راهنمای فایلهای مهم وردپرس و مقاله جلوگیری از هکشدن سایت وردپرسی میتوانند برای تکمیل چکلیست امنیتی مفید باشند.
جمعبندی
برای کاهش خطر اجرای مستقیم فایلهای PHP بارگذاریشده، میتوانید در Apache 2.4 یا LiteSpeed سازگار، قاعده محدودکننده را در فایل .htaccess داخل wp-content/uploads قرار دهید و نتیجه را کنترلشده آزمایش کنید.
پوشه wp-includes به دلیل نقش آن در هسته وردپرس به قواعد دقیقتر و بررسی سازگاری نیاز دارد؛ بهخصوص در Multisite. در نهایت، محدودسازی آپلود، مجوزهای مناسب، بهروزرسانی مداوم و پشتیبانگیری قابلبازیابی را در کنار این تنظیم اجرا کنید.





