جلوگیری از اجرای فایل PHP در پوشه wp-content
- امنیت وردپرسمقالات آموزشی
- بروزرسانی شده در

ببینید، وردپرس ذاتاً یهسری پوشه رو قابل نوشتن (Writable) نگه میداره. دلیلش هم کاملاً منطقیه: شما باید بتونید قالب نصب کنید، افزونه آپلود کنید، عکس و ویدیو بذارید. اگه این پوشهها قفل بودن که اصلاً نمیشد باهاشون کار کرد.
ولی همین قابلیت خوب، یه روی تاریک هم داره. اگه یه هکر بتونه از یه راهی، مثلاً یه افزونهی آسیبپذیر یا یه فرم آپلود بیدرپیکر، یه فایل PHP توی پوشهی uploads بذاره، عملاً کلید خونه رو دستش دادید. اون فایل بیسروصدا اجرا میشه، توی پسزمینه کار خودش رو میکنه و به کل سایت شما دسترسی کامل پیدا میکنه.
خبر خوب اینه که راهحلش واقعاً سادهست. انقدر ساده که وقتی انجامش بدید با خودتون میگید «همین بود؟». تو این مقاله قدمبهقدم میریم جلو تا اجرای PHP رو توی پوشههایی که اصلاً بهش نیازی ندارن ببندیم.
آنچه در این مقاله میخوانید
چرا اجرای فایل PHP در wp-content خطرناک است؟
بذارید یه چیزی رو روشن کنیم. مشکل خودِ زبان PHP نیست، مشکل جاییه که اجرا میشه.
پوشههای قابل نوشتن وردپرس
توی یه نصب استاندارد وردپرس، این پوشهها معمولاً دسترسی نوشتن دارن:
/wp-content/uploads/که همهی تصاویر، PDFها و فایلهایی که آپلود میکنید اینجان/wp-content/plugins/که افزونهها اینجا نصب میشن/wp-content/themes/که قالبها اینجا میشینن/wp-content/cache/اگه افزونهی کش داشته باشید
حالا سؤال کلیدی اینه: توی پوشهی uploads که فقط قراره عکس و فایل داشته باشه، اصلاً چه دلیلی داره که یه فایل .php اجرا بشه؟ هیچی. صفر. پس چرا بذاریم اجازهش باشه؟
بکدور (Backdoor) و وبشل چیست؟
بکدور دقیقاً همونیه که از اسمش پیداست، یه درِ پشتی. یه فایل کوچیک که هکر میذاره تا هر وقت خواست، بدون نیاز به رمز عبور، برگرده تو سایت شما.
وبشل هم برادر بزرگتر همینه. یه فایل PHP که وقتی توی مرورگر بازش کنید، یه پنل مدیریت کامل بهتون میده: فایلها رو ببین، دیتابیس رو بخون، دستور اجرا کن. یعنی طرف از توی مرورگر خودش داره روی سرور شما کار میکنه.
بدترین قسمت ماجرا اینه که اینا معمولاً چند کیلوبایت بیشتر نیستن و یه اسم بیآزار مثل wp-cache-index.php یا class-wp-loader.php روشون میذارن. یعنی وقتی دارید فایلهای هاست رو نگاه میکنید، اصلاً به چشمتون نمیاد.
چرا فایلهای مخرب خودشون را شبیه فایلهای وردپرس جا میزنند؟
چون کار میکنه! شما چند بار کل فایلهای wp-includes رو یکییکی چک کردید؟ هیچکس این کارو نمیکنه. هکرها هم اینو خوب میدونن. برای همین بهجای اینکه فایلشون رو hack.php بذارن، اسمی انتخاب میکنن که کنار بقیهی فایلها گم بشه.
فایل htaccess چیست و کجاست؟

اگه هاستتون آپاچی (Apache) یا لایتاسپید (LiteSpeed) باشه، که اکثر هاستهای اشتراکی همینن، یه فایل به اسم .htaccess توی پوشهی اصلی سایتتون دارید.
این فایل یه جور دفترچهی دستوره برای وبسرور. هر خطی که توش بنویسید، سرور قبل از سرو کردن صفحه اونو میخونه و اعمال میکنه.
کاربرد htaccess
خیلی بیشتر از اونی که فکرشو میکنید:
- رمزگذاری روی پنل مدیریت
- غیرفعال کردن نمایش لیست فایلهای یه پوشه
- ساختن پیوند یکتاهای سئوشده (همون کاری که وردپرس خودکار انجام میده)
- ریدایرکت ۳۰۱
- و کاری که ما میخوایم بکنیم، یعنی بستن اجرای PHP
چطور پیداش کنیم؟
نکتهی مهم: چون اسم فایل با نقطه شروع میشه، بهصورت پیشفرض مخفیه. باید توی فایل منیجر سیپنل برید تو تنظیمات (Settings) و تیک Show Hidden Files (dotfiles) رو بزنید. توی FTP هم معمولاً از منوی Server گزینهی Force showing hidden files رو دارید.

نکتهی دوم و مهمتر: .htaccess فقط مخصوص پوشهی اصلی نیست. میتونید توی هر پوشهی داخلی یه فایل جدا بذارید و قوانین مخصوص همون پوشه رو بنویسید. کل ترفند ما دقیقاً روی همین بنا شده.
آموزش گامبهگام بستن اجرای PHP با htaccess
خب بریم سر اصل مطلب. کل ماجرا پنج دقیقه بیشتر وقت نمیبره.
گام اول: یک فایل خالی بسازید
روی کامپیوترتون Notepad (یا بهتر، Notepad++ یا VS Code) رو باز کنید و یه فایل خالی جدید بسازید.
حواستون باشه: با Notepad ویندوز اگه ذخیره کنید، ممکنه پشت اسم فایل یه
.txtبچسبونه. موقع ذخیره حتماً توی قسمت Save as type گزینهیAll Filesرو بزنید و اسم رو دقیقاً.htaccessبنویسید.
گام دوم: کد رو بنویسید
این سه خط رو بذارید توش:
apache
<Files *.php>deny from all</Files>ترجمهی فارسیش میشه: «هر فایلی که پسوندش php هست رو، به هیچکس نشون نده و اجراش نکن.» تمام.
گام سوم: بدانید کجا آپلودش کنید
این فایل رو باید توی این پوشهها بذارید:
/wp-includes//wp-content/uploads/
اگه میخواید سختگیرتر باشید، /wp-content/plugins/ و /wp-content/themes/ رو هم میتونید اضافه کنید. ولی صبر کنید، دربارهی این دوتا یه هشدار مهم داریم که پایینتر توی بخش عیبیابی میگیم. فعلاً از همون دوتای اول شروع کنید.
مهم: این فایل رو توی پوشهی اصلی (Root) سایتتون نذارید! اونجا .htaccess خودِ وردپرس هست و اگه این کد رو بهش اضافه کنید، index.php سایت هم بلاک میشه و کل سایتتون میره روی هوا.
گام چهارم: آپلود کنید
دو تا راه دارید:
با FTP: با فایلزیلا وصل بشید، برید توی پوشهی مقصد، فایل رو بکشید و رها کنید. تمام.

با سیپنل: برید توی File Manager، وارد پوشهی مورد نظر بشید، از بالا دکمهی Upload رو بزنید و فایلتون رو انتخاب کنید.

اگه اصلاً حوصلهی ساختن فایل روی سیستمتون رو ندارید، توی سیپنل میتونید مستقیم + File بزنید، اسمشو .htaccess بذارید، بعد راستکلیک کنید، Edit رو بزنید و کد رو همونجا تایپ کنید.
گام پنجم: تست کنید ببینید واقعاً کار میکند
این قسمت رو خیلیها ول میکنن و بعداً میگن «مطمئن نیستم کار کرد یا نه». پس انجامش بدید:
۱. یه فایل به اسم test.php بسازید و توش بنویسید: <?php echo "salam"; ?>
۲. آپلودش کنید توی /wp-content/uploads/ .
توی مرورگر برید به https://yoursite.com/wp-content/uploads/test.php
اگه خطای 403 Forbidden گرفتید، تبریک میگیم، کار کرد. اگه کلمهی «salam» رو دیدید، یعنی یه جای کار میلنگه (احتمالاً فایل جای اشتباه آپلود شده یا سرورتون Nginx هست که پایینتر توضیح میدیم).
بعد از تست، یادتون نره test.php رو پاک کنید.
عیبیابی: وقتی این کد با افزونهها دعواش میشه
خب حالا بریم سراغ اون قسمتی که هیچ مقالهای بهتون نمیگه.
کد deny from allامنیت رو میبره بالاترین حد ممکن، ولی چون مطلق عمل میکنه، ممکنه پای بعضی افزونههای سالم رو هم قطع کنه.
نشانههای تداخل چیست؟
بعد از آپلود فایل، اگه یکی از اینا رو دیدید، بدونید که تداخل دارید:
- تصاویر سایت لود نمیشن یا آیکون شکسته نشون میده
- یه ابزارک یا بخشی از صفحهساز (المنتور، WPBakery و…) از کار افتاده
- افزونهی بهینهسازی تصویر خطا میده
- گالری یا اسلایدر خالی نشون داده میشه
دلیلش اینه که بعضی افزونههای معتبر، مخصوصاً افزونههای بهینهسازی تصویر، امنیتی و صفحهسازها، برای کار کردن نیاز دارن یه اسکریپت PHP خاص رو مستقیم از توی پوشههای داخلی صدا بزنن.
راهحل هوشمندانه: مسدود کنید ولی با استثنا
بهجای اینکه در رو کامل ببندید، بیاید هوشمندانهتر عمل کنیم. این کد فایلهای PHP رو میبنده ولی راه رو برای عکس، CSS و جاوااسکریپت باز نگه میداره:
apache
<Files *.php> Order Allow,Deny Deny from all</Files># اجازه دسترسی به فایلهای ضروری رسانه و طراحی<FilesMatch "\.(jpg|jpeg|png|gif|webp|svg|css|js|woff|woff2)$"> Order Allow,Deny Allow from all</FilesMatch>راستی، توی نسخههای قدیمیتر این کد که تو اینترنت دستبهدست میشه،
jpegدو بار تکرار شده وwebpوsvgهم اصلاً نیست. ما اینجا درستش کردیم و فونتها رو هم اضافه کردیم، چون خیلی از قالبها فونتهاشون رو از توی uploads لود میکنن.
اگر یک افزونهی خاص مشکل داشت چه کنیم؟
فرض کنید فهمیدید افزونهی X برای کار کردن به فایل handler.php نیاز داره. لازم نیست کل امنیت رو بیخیال بشید. فقط برای همون یه فایل استثنا قائل بشید:
apache
<Files "handler.php"> Order Deny,Allow Allow from all</Files>این بلاک رو بعد از بلاک اصلی بذارید. اینجوری فقط همون یه فایل مجوز میگیره و بقیه همچنان بسته میمونن.
چطور بفهمیم کدوم فایل مشکل داره؟ توی مرورگر F12 رو بزنید، برید تب Console یا Network، صفحه رو رفرش کنید و دنبال خطاهای قرمز با کد ۴۰۳ بگردید. اسم فایلی که بلاک شده همونجا نوشته شده.
راه حل برای سرورهای Nginx
اینو با دقت بخونید، چون خیلیها اینجا گول میخورن.
فایل .htaccess فقط روی آپاچی و لایتاسپید کار میکنه. اگه سایتتون روی یه سرور مجازی یا اختصاصی با وبسرور Nginx بالا اومده، Nginx اصلاً این فایل رو نمیخونه. کاملاً نادیدهش میگیره.
یعنی چی؟ یعنی ممکنه فایل رو آپلود کرده باشید، خیالتون راحت باشه که سایتتون امنه، ولی در واقع هیچ اتفاقی نیفتاده باشه. برای همینه که گفتیم حتماً تست کنید.
نحوه فهمیدن نوع سرور
سادهترین راه: توی مرورگر F12 بزنید، برید تب Network، صفحه رو رفرش کنید، روی اولین درخواست کلیک کنید و توی Response Headers دنبال Server بگردید. اسم وبسرورتون اونجا نوشته شده.

کد مخصوص Nginx
توی Nginx باید مستقیم برید سراغ فایل کانفیگ سرور (معمولاً توی /etc/nginx/sites-available/). این بلاک رو داخل بخش server اضافه کنید:
nginx
location ~* ^/(wp-content|wp-includes)/.*\.php$ { deny all; access_log off; log_not_found off;}بعد از اضافه کردن، اول تنظیمات رو تست کنید:
bash
nginx -tاگه پیغام syntax is ok گرفتید، حالا ریاستارت کنید:
bash
systemctl restart nginxهشدار: اگه بدون
nginx -tمستقیم ریاستارت بزنید و کد ایراد داشته باشه، Nginx بالا نمیاد و کل سایتتون میافته. این دستور رو جدی بگیرید.
مخفی کردن خود فایل htaccess
حالا که این همه قانون امنیتی توی .htaccess نوشتید، بد نیست کاری کنید که هیچکس نتونه محتواش رو ببینه.
فایلهای پیکربندی مثل .htaccess و wp-config.php حساسترین اطلاعات سایتتون رو دارن. اگه یه نفر بتونه محتواشون رو بخونه، عملاً نقشهی دفاعیتون رو دستش دادید.
این کد رو توی .htaccess پوشهی اصلی سایتتون اضافه کنید:
apache
<Files ~ "^.*\.([Hh][Tt][Aa])"> Order allow,deny Deny from all Satisfy All</Files>اون [Hh][Tt][Aa] هم برای اینه که فرقی نکنه با حروف بزرگ نوشته شده یا کوچیک، همهش بلاک میشه.
سطح دسترسی (Permission) را درست تنظیم کنید
بذارید یه چیزی بهتون بگیم که خیلی مهمه: آپلود کردن .htaccess نصف کاره.
فکر کنید یه هکر تونست وارد پوشههاتون بشه. اولین کاری که میکنه چیه؟ همین فایل امنیتی شما رو پاک میکنه یا محتواش رو خالی میکنه. برای همین باید کاری کنید که حتی اگه یه اسکریپت مخرب رفت داخل، نتونه فایلهای شما رو دستکاری کنه.
طبق استانداردهای رسمی وردپرس:
| مورد | سطح دسترسی |
|---|---|
| همهی پوشهها | 755 |
| همهی فایلها | 644 |
فایل wp-config.php | 440 یا 400 |
نحوه تغییر سطح دسترسی
توی سیپنل، فایل منیجر رو باز کنید، روی پوشه یا فایل راستکلیک کنید و Change Permissions رو بزنید. عدد رو وارد کنید و ذخیره کنید. البته در مقاله سطح دسترسی چیست؟ تغییر سطح دسترسی یا پرمیشن فایلها در وردپرس کامل توضیح دادیم.

اگه دسترسی SSH دارید، این دوتا دستور کل کار رو یهجا انجام میده:
bash
find /path/to/wordpress/ -type d -exec chmod 755 {} \;
find /path/to/wordpress/ -type f -exec chmod 644 {} \;هیچوقت، تحت هیچ شرایطی، پرمیشن ۷۷۷ نذارید. حتی اگه یه آموزش یا پشتیبانی هاست بهتون گفت. عدد ۷۷۷ یعنی «هر کسی از هر جایی هر کاری خواست بکنه».
چند تا نکتهی تکمیلی که ارزش وقت گذاشتن دارن
حالا که دستتون تو کاره، این سه تا رو هم انجام بدید. مجموعش ده دقیقه وقت میبره ولی خیلی فرق ایجاد میکنه.
بستن ویرایشگر فایل پیشخوان
وردپرس یه ویرایشگر داره توی مسیر ظاهر و افزونهها که میتونید مستقیم کد قالب رو ویرایش کنید. اگه یه نفر به پنل مدیرتون دسترسی پیدا کنه، از همینجا کد مخرب تزریق میکنه.
این خط رو توی wp-config.php اضافه کنید:
php
define('DISALLOW_FILE_EDIT', true);نمایش لیست فایلهای پوشه را غیرفعال کنید
اگه کسی بره به yoursite.com/wp-content/uploads/ و لیست همهی فایلهاتون رو ببینه، خیلی بد میشه. این خط رو توی .htaccess اصلی بذارید:
apache
Options -Indexesاز wp-config.php محافظت کنید
مهمترین فایل سایتتونه و اطلاعات دیتابیس توشه. این کد رو توی .htaccess اصلی اضافه کنید:
apache
<Files wp-config.php> Order Allow,Deny Deny from all</Files>سؤالات متداول
این کد سرعت سایتمون رو کم میکنه؟
نه. بار پردازشی این قوانین انقدر ناچیزه که اصلاً قابل اندازهگیری نیست. (فقط اگه سرورتون Nginx باشه و بخواید .htaccess رو فعال کنید، اون داستان دیگهایه که اصلاً نباید سراغش برید.)
سایتمون قبلاً هک شده، این روش درستش میکنه؟
نه، متأسفانه. این روش پیشگیرانهست، نه درمانی. اگه بکدور از قبل روی سایتتون باشه، ممکنه جاهای دیگهای هم خودش رو کپی کرده باشه: توی دیتابیس، توی فایلهای اصلی، حتی توی جدول کاربران. برای سایت هکشده باید کل فایلها رو اسکن کنید، رمزها و Salt keyها رو عوض کنید و فایلهای هسته رو با نسخهی سالم جایگزین کنید.
توی پوشهی plugins و themes هم بذاریم؟
با احتیاط. خیلی از افزونهها و قالبها فایلهای PHP رو مستقیم صدا میزنن (مثلاً برای AJAX یا آپلود). اگه اونجا هم بذارید، احتمال خرابی بالاست. توصیهی ما اینه که از uploads و wp-includes شروع کنید. اگه خواستید برای plugins هم بذارید، حتماً از نسخهی استثنادار استفاده کنید و بعدش کل سایت رو تست کنید.
بعد از آپلود خطای 500 گرفتیم، چیکار کنیم؟
احتمالاً یه تایپو توی کد دارید یا سرورتون یکی از این دستورات رو پشتیبانی نمیکنه. اول از همه فایل رو موقتاً پاک کنید (یا اسمشو بذارید htaccess-off) تا سایت برگرده. بعد کد رو خطبهخط اضافه کنید ببینید کدوم خط باعث خطا میشه.
آپدیت وردپرس این فایل رو پاک میکنه؟
فایلهایی که خودتون توی uploads گذاشتید نه. ولی حواستون باشه wp-includes موقع آپدیت هسته بازنویسی میشه، پس بعد از هر آپدیت بزرگ یه سر بزنید ببینید فایلتون سرجاشه.
جمعبندی
خلاصهی کل ماجرا:
- توی
/wp-content/uploads/و/wp-includes/یه فایل.htaccessبذارید و اجرای PHP رو ببندید - حتماً تست کنید که واقعاً کار میکنه، با یه
test.phpساده - اگه سرورتون Nginx هست،
.htaccessبیفایدهست و باید برید سراغ فایل کانفیگ - پرمیشن پوشهها ۷۵۵ و فایلها ۶۴۴ باشه
- ویرایشگر فایل پیشخوان رو ببندید و از
wp-config.phpمحافظت کنید
و آخرین حرفمون: امنیت یه کار یهباره نیست. این کارا سطح حمله رو خیلی کم میکنه، ولی جای بکآپ منظم، آپدیت بهموقع و رمز عبور قوی رو نمیگیره. بکدورها هوشمندانه پنهان میشن، پس همیشه یه چشمتون به سایتتون باشه.

سلام
سایت وردپرس ام دسترسی به افزونه ها و بخش های دیگه ندادم و خطای ۴۰۳ میده احتمالا دچار حمله شده چون htaccess هاست تغییر کرده و هرچه ویرایش یا حذف میکنم دوباره ایجاد میشه و کدهای هم نمیتونم تغییر بدم
لطفا راهنمایی کنید
سلام
این آموزش رو مشاهده کنیدپ
https://mihanwp.com/403-error/
با سلام
بابت این نوشته ممنونم اما چند سوآل برایم پیش آمده که اگر پاسخ بدهید سپاسگزار خواهم بود.
۱- منظورتان این چهار پوشه است: wp-includes و plugins و uploads و themes؟ چون متن انگلیسی بالا به نظر میآید به هم ریخته باشد.
۲- پوشهی wp-content نیازی ندارد؟
۳- آیا ممکن است اجرای این کد در آینده برای برخی از عملکردهای صحیح سایت مشکلی درست کند؟ مثلاً اجرای برخی دستورات یا افزونهها و قالبها؟
درود بر شما
۱. بله
۲. خیر چون فایلهای قالب و افزونهها در آن قرار دارند.
۳. خیر
سلام خسته نباشید
می خواستم بدونم چرا در هاست من هم فایل wp-config هستش و هم فایل wp-config-sample ؟
و آیا اینکه وجود همزمان این 2 تا فایل از نظر امنیتی مشکلی رو واسه سایت من به وجود نمی آره ؟
سلام خیر مشکلی نیست. sample برای نصب وردپرس هست و بعد از نصب هیچ تاثیری نداره میتونید حذفش کنید حتی
ممنون از این که راهنمایی کردید
دیدم این آموزش رو
متاسفانه وقتی حذف میکنم htaccess رو و میرم پیشخوان قسمت پیوند یکتا بهم اجازه دسترسی نمیده و خطای ۴۰۳ میده کلا به افزونه ها و تنظیمات و بقیه قسمت پیشخوان دسترسی ندارم و روش میزنم خطای ۴۰۳ میده
این فایل htaccess هم هرچی کدشو تغییر میدم باز اون کد مخرب روش نوشته میشه
انگار به خاطر همین کدی که به طور خودکار روی htaccess نوشته میشه دسترسی به قسمت های مختلف پیشخوان گرفته شده
نمیدونم چطور میتونم جلوی نوشتن خودکار htaccess رو بگیرم
شما اول باید فرایند پاکسازی سایت ویروسی رو انجام بدین. سپس کد رو تغییر بدید توی این فایل