الانتقال إلى المحتوى
الخادم و .htaccess

قواعد حماية ملف htaccess في ووردبريس التي تفيد فعلاً

معظم ما يُسوَّق على أنه حماية لملف htaccess في ووردبريس مجرد حشو. القواعد التي تُغيّر سطح الهجوم فعلاً قليلة ومختصرة — وهنا نميّز الغثّ من السمين

نُشر

معظم ما يُسوَّق على أنه “حماية ملف htaccess في ووردبريس” مجرد حشو. القواعد التي تُغيّر سطح الهجوم فعلاً قليلة ومختصرة: منع تنفيذ ملفات PHP داخل wp-content/uploads، ومنع الوصول المباشر إلى wp-config.php، وتعطيل فهرسة المجلدات. أما القواعد الشائعة — حجب xmlrpc.php “لإيقاف هجمات التخمين”، وإخفاء إصدار ووردبريس، ولصق قائمة من 200 سطر بأسماء وكلاء المستخدم الخبيثة — فتتراوح بين قليلة الجدوى والمسرحية البحتة. وفيما يلي نميّز الغثّ من السمين، ولماذا.

نقطة يجب حسمها أولاً: ملف .htaccess لا يفعل شيئاً إلا على خادم Apache (و LiteSpeed الذي يقرأه هو الآخر). أما على nginx فهو مُتجاهَل تماماً — يبقى الملف موجوداً بينما تظن أنك محميّ. إن كان خادمك يعمل بـ nginx، فلا شيء من هذا ينطبق، وستحتاج بدلاً منه إلى كتل server/location. تحقق باستخدام curl -I https://yoursite.com وانظر إلى ترويسة Server: قبل أن تضيّع ساعة في تحرير ملف لا يقرأه الخادم أصلاً.

القاعدة التي تهمّ فعلاً: لا PHP في /uploads

هذه هي القاعدة التي تستحق التطبيق. مجلد wp-content/uploads قابل للكتابة عالمياً بحكم تصميمه — كل رفع للوسائط، وكل إضافة تحفظ ملفاً، تكتب فيه. إذا نجح مهاجم في إدخال ملف .php إلى هذا المجلد (عبر معالج رفع مصاب بثغرة، أو حقل صورة لا يتحقق من نوع MIME، أو إضافة مخترقة)، فإن الفرق بين مجرد إزعاج واختراق كامل ينتهي بتنفيذ التعليمات عن بُعد هو ما إذا كان الخادم سيقوم بتنفيذ ذلك الملف عند طلبه. امنع التنفيذ، وتصبح الحمولة المرفوعة مجرد ملف خامل يقبع على القرص.

أضف هذا إلى wp-content/uploads/.htaccess (أنشئ الملف إن لم يكن موجوداً):

<FilesMatch "\.php$">
    Require all denied
</FilesMatch>

هذه صيغة Apache 2.4. أما في الإصدار الأقدم 2.2، فالمكافئ هو Order Deny,Allow / Deny from all. خلط اللهجتين في ملف واحد هو أكثر أسباب ظهور 500 Internal Server Error المفاجئ شيوعاً بعد “التحصين” — إن انهار الموقع بأكمله لحظة الحفظ، فهذا هو السبب في الغالب. تحقق من إصدارك باستخدام apachectl -v.

حماية ملف wp-config.php

يحتوي ملف wp-config.php على بيانات اعتماد قاعدة بياناتك ومفاتيح المصادقة (salts). ما دام PHP يعمل، فإن الطلب المباشر لهذا الملف يُرجع صفحة فارغة — إذ ينفّذ PHP الملف بدل طباعته. الخطر يكمن في حالة الفشل: إذا تعطّل PHP في أي وقت، أو أُسيء ضبطه أثناء عملية نقل، أو عُطِّل معالجه، فإن Apache يقدّم الملف كنص عادي ويكشف كلمة مرور قاعدة بياناتك لأي طالب. منع الوصول تأمين رخيص ضد خمس دقائق سيئة:

<Files wp-config.php>
    Require all denied
</Files>

تعطيل فهرسة المجلدات

إذا زار أحدهم مجلداً لا يحتوي على index.php وكان Apache مضبوطاً على Options +Indexes، فإنه يعرض محتوياته — كل ملف نسخ احتياطي، وكل ملف SQL شارد نسيته. عطّل ذلك على مستوى الموقع كله:

Options -Indexes

خطورته منخفضة، لكنها حقيقية، ولا يكلّف شيئاً.

هذه هي القائمة الأساسية الصادقة. يمكنك تجميع هذه القواعد — مع الصيغة الصحيحة بين 2.4 و 2.2 كي لا يقع موقعك في خطأ 500 — باستخدام مولّد ملف htaccess لووردبريس بدلاً من النسخ واللصق من مشاركة منتدى كُتبت لإصدار Apache خاطئ.

ما لا ينبغي فعله

حجب xmlrpc.php “للحماية من التخمين”. هذه هي المقولة الكبرى التي يكررها الجميع، وهي خاطئة كما تُصاغ. نعم، تاريخياً كانت طريقة system.multicall في XML-RPC تتيح للمهاجم تجميع عدد كبير من محاولات تسجيل الدخول في طلب واحد — تضخيم حقيقي. لكن ناقل التخمين الأكثر شيوعاً بمراحل هو طلبات POST البسيطة إلى wp-login.php، وحجب xmlrpc.php لا يفعل شيئاً حيال ذلك. يُهزم التخمين بتحديد معدل الطلبات، وكلمات المرور القوية، والمصادقة الثنائية — لا بقتل نقطة نهاية واحدة. يوجد سبب مشروع لتعطيل XML-RPC: يمكن استغلال ميزة pingback فيه لعكس هجمات DDoS، فإن كنت لا تستخدم Jetpack ولا تطبيق الجوال ولا الـ pingbacks، فإغلاقه يقلّص سطح الهجوم. فقط لا تُوهم نفسك أنه دفاعك ضد التخمين، لأنه ليس كذلك.

إخفاء إصدار ووردبريس / إزالة وسم المولّد. إزالة readme.html ووسم <meta name="generator"> تبدو كأنها تحصين. لكن المهاجم يبصم إصدارك من سلاسل استعلامات الأصول المُدرَجة، ومن ترميز محرر الكتل، ومن عشرات المؤشرات الأخرى في ثوانٍ. أنت لا تخفي شيئاً؛ أنت فقط توهم نفسك بأنك مشغول.

قوائم الحجب الضخمة لوكلاء المستخدم الخبيثين والمُحيلين. وكيل المستخدم مجرد ترويسة HTTP واحدة يسهل تزويرها. هذه القوائم قديمة يوم لصقها، ولا تحجب أي مهاجم كفؤ، و Apache يقيّم كل تعبير نمطي على كل طلب — فأنت تدفع ضريبة أداء حقيقية مقابل صفر أمان. تجاوزها.

قفل wp-login.php على عنوان IP معيّن. رائع إلى أن يبدّل مزوّد خدمتك عنوانك فتقفل نفسك خارج لوحة تحكمك. لا يصلح إلا مع عنوان IP ثابت فعلاً.

تحويلات تعداد المؤلفين (?author=1). إعادة الكتابة التي يلصقها الناس في .htaccess لهذا الغرض ناقصة بذاتها — إذ لا تزال نقطة نهاية REST المسمّاة /wp-json/wp/v2/users تسرد أسماء المستخدمين. حجب مسار واحد بينما يبقى الآخر مفتوحاً مجرد مسرحية.

ما زلت عالقاً؟

إن أوقع أحد القواعد الموقع في خطأ 500، فالمشكلة في الصيغة — احذف آخر كتلة أضفتها وأعد التحميل؛ فهذا يعزلها فوراً. إن بدت قاعدة ما بلا أثر، فتأكد أنك فعلاً على Apache وأن AllowOverride مُفعّل لذلك المجلد (كثير من الاستضافات المُدارة تقيّده). ابنِ الملف من قالب معروف الصحة باستخدام مولّد ملف htaccess، واحتفظ بالقواعد الثلاث التي تهمّ، واترك الباقي.

FAQ

أسئلة

كيف أمنع تنفيذ ملفات PHP داخل مجلد الرفع في WordPress؟

أنشئ ملف .htaccess داخل wp-content/uploads يحتوي كتلة FilesMatch تطابق ملفات .php مع Require all denied. فمجلد الرفع قابل للكتابة عالمياً بحكم تصميمه، ومنع التنفيذ يعني أن ملف .php خبيثاً يتسلّل إليه يبقى ملفاً خاملاً على القرص بدل أن يتحوّل إلى تنفيذ تعليمات عن بُعد.

هل أحتاج إلى منع الوصول المباشر إلى wp-config.php؟

نعم، وهي قاعدة لا تكلّف شيئاً. أضف كتلة Files لملف wp-config.php مع Require all denied. فما دام PHP يعمل، لا يعيد الطلب المباشر إلا صفحة فارغة، لكن إذا انهار PHP أو أُسيء ضبطه أثناء ترحيل أو عُطّل معالجه، قدّم Apache الملف نصاً صريحاً وكشف بيانات اعتماد قاعدة بياناتك.

لماذا ظهر خطأ 500 Internal Server Error فور تعديلي لملف htaccess؟

السبب في الغالب خلط صيغ Apache. فـ Require all denied من Apache 2.4، بينما Order Deny,Allow مع Deny from all من 2.2، والجمع بين اللهجتين في ملف واحد يكسر الموقع لحظة الحفظ. تحقق من إصدارك بالأمر apachectl -v، أو احذف آخر كتلة أضفتها وأعد التحميل.

هل يعمل ملف htaccess على nginx؟

لا. ملف .htaccess لا يفعل شيئاً إلا على Apache، وعلى LiteSpeed الذي يقرأه هو الآخر. أما على nginx فهو متجاهَل تماماً، فيبقى موجوداً بينما تظن أنك محميّ. شغّل curl -I على موقعك وانظر إلى ترويسة Server: أولاً، ثم استخدم كتل server أو location بدلاً منه.

هل يوقف حجب xmlrpc.php هجمات التخمين على WordPress؟

لا. فمسار التخمين الأكثر شيوعاً بفارق كبير هو طلبات POST عادية إلى wp-login.php، وحجب xmlrpc.php لا يفعل شيئاً حيالها. التخمين يُهزَم بتحديد معدّل الطلبات وكلمات المرور القوية والتحقق بخطوتين. ومع ذلك يبقى تعطيل XML-RPC مفيداً إن كنت لا تستخدم Jetpack ولا تطبيق الهاتف ولا التنبيهات المرجعية، لأن التنبيه المرجعي يمكن استغلاله في هجمات حجب الخدمة الانعكاسية.