2026年11月12日
2026年11月12日
إخفاء إصدار WordPress: وسم generator وكلمة ver= وملف readme.html
هذه المقالة نسخة مُوطَّنة من الأصل الياباني. اقرأ الأصل الياباني
يكتب WordPress رقم إصداره افتراضيًا في HTML الصفحات وفي الخلاصات (Feeds). وقد يستخدم المهاجم هذا الرقم دليلًا لمعرفة هل الإصدار فيه ثغرات معروفة. تشرح هذه المقالة أماكن ظهور الإصدار وخطوات إخفائه. المحتوى وفق وضع أكتوبر 2026.
أول ما ينبغي معرفته أن إخفاء الإصدار إجراء مساعد. فهناك طرق لتخمين الإصدار من محتوى ملفات CSS وJavaScript وغيرها، لذلك لا يضمن الإخفاء منع التعرّف عليه. والأكثر فاعلية هو إبقاء نواة WordPress والإضافات والقوالب محدَّثة.
أماكن ظهور الإصدار
| المكان | ما يظهر | المعالجة |
|---|---|---|
<head> في HTML |
وسم مثل <meta name="generator" content="WordPress 6.9.4"> |
الفلتر the_generator |
| خلاصات RSS وAtom | سطر مثل <generator>https://wordpress.org/?v=6.9.4</generator> |
الفلتر the_generator نفسه |
| روابط CSS وJavaScript | ?ver= مثل style.min.css?ver=6.9.4 |
الفلترَان style_loader_src وscript_loader_src |
| ترويسة HTTP | X-Powered-By: PHP/8.3.x (إصدار PHP لا WordPress) |
expose_php في php.ini |
readme.html |
أنك تستخدم WordPress (لا يتضمن readme.html الحالي رقم إصدار) | رفض الوصول إليه |
لا تتضمن معلومات الموقع التي يعيدها /wp-json/ في REST API (الاسم والوصف وعنوان URL والمنطقة الزمنية ومساحات الأسماء وغيرها) إصدار WordPress. فلا حاجة إلى حذف شيء من مخرجات REST API بغرض إخفاء الإصدار.
الخطوة 1: تحقق من الوضع الحالي للعرض
غيّر العنوان إلى عنوان موقعك ونفّذ الأوامر على جهازك أو على الخادم. وإذا كنت تستخدم إضافات كاش أو CDN فامسح الكاش بعد التغيير ثم تحقق.
# وسم generator في HTML
curl -s https://example.com/ | grep -i 'name="generator"'
# generator في الخلاصة
curl -s https://example.com/feed/ | grep -i '<generator>'
# قائمة قيم ver= الموجودة في CSS وJS
curl -s https://example.com/ | grep -oE 'ver=[0-9][0-9.]*' | sort | uniq -c
# الترويسة X-Powered-By في HTTP
curl -sI https://example.com/ | grep -i 'x-powered-by'
# هل يمكن قراءة readme.html (200 تعني أنه مقروء)
curl -s -o /dev/null -w '%{http_code}\n' https://example.com/readme.html
إذا كانت في قائمة ver= قيمة مطابقة لإصدار WordPress الظاهر في «لوحة التحكم ← التحديثات» (Dashboard → Updates) فهذا يعني أنه يمكن معرفة إصدار WordPress من ملفات CSS وJS تلك. فعندما تحمّل نواة WordPress أو القالب ملفات CSS وJS دون تحديد إصدار، يدخل إصدار WordPress في ver=.
الخطوة 2: حدّد مكان وضع الشيفرة
ضع شيفرة هذه المقالة في أحد موضعين.
- mu-plugin (الموصى به): ضع ملف PHP في المجلد
wp-content/mu-plugins/(أنشئه إن لم يوجد) فيُحمَّل دون خطوة تفعيل، ويستمر أثره حتى لو غيّرت القالب - functions.php في قالب فرعي: إذا كتبتها في functions.php للقالب الأصل فستُمحى عند تحديث القالب
إذا اخترت mu-plugin فاحفظ شيفرة الخطوة التالية كلها في ملف واحد باسم مثل wp-content/mu-plugins/hide-wp-version.php.
الخطوة 3: إخفاء إصدار وسم generator و ver=
<?php
/**
* Plugin Name: Hide WordPress Version
* Description: يخفي وسم generator وإصدار WordPress الظاهر في ver= بملفات CSS وJS.
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
// يفرّغ <meta name="generator"> في HTML و<generator> في الخلاصة.
add_filter( 'the_generator', '__return_empty_string' );
/**
* يستبدل قيمة ver= في CSS وJS بقيمة أخرى فقط عندما تساوي إصدار WordPress.
* ولأنه يستبدل ver= ولا يحذفه، يتحدّث كاش المتصفح بعد تحديث WordPress أيضًا.
*/
function wpdr_replace_wp_version_query( $src ) {
if ( ! is_string( $src ) || '' === $src ) {
return $src;
}
$query = wp_parse_url( $src, PHP_URL_QUERY );
if ( empty( $query ) ) {
return $src;
}
parse_str( $query, $args );
$wp_version = get_bloginfo( 'version' );
if ( isset( $args['ver'] ) && $args['ver'] === $wp_version ) {
$src = add_query_arg( 'ver', substr( wp_hash( $wp_version ), 0, 10 ), $src );
}
return $src;
}
add_filter( 'style_loader_src', 'wpdr_replace_wp_version_query', 20 );
add_filter( 'script_loader_src', 'wpdr_replace_wp_version_query', 20 );
النقاط المهمة هي الآتية.
- يؤثر الفلتر
the_generatorفي وسم generator في HTML وفي generator الخلاصات معًا. أماremove_action( 'wp_head', 'wp_generator' );فيزيل وسم HTML فقط، فلا يؤثر في الخلاصات - إذا حذفت
?ver=كله فقد يستمر المتصفح في استخدام CSS وJS القديمين بعد تحديث إضافة أو قالب. تستبدل الشيفرة أعلاه القيمة بسلسلة أخرى مشتقة من الإصدار عندما تساوي إصدار WordPress فقط. وتتغير القيمة عند تحديث WordPress فيتحدّث كاش المتصفح - لا تُغيَّر قيم
ver=التي تضع فيها الإضافات أو القوالب أرقام إصداراتها الخاصة
بعد الحفظ تحقق بأوامر الخطوة 1 من أن generator لا يظهر، ومن عدم بقاء إصدار WordPress في قائمة ver=. وإذا كنت تستخدم إضافة كاش فامسح الكاش قبل التحقق.
الخطوة 4: إيقاف ترويسة X-Powered-By
الترويسة X-Powered-By تضيفها PHP لا WordPress، وتكشف إصدار PHP. لإيقافها اضبط expose_php على Off في ملف إعداد PHP (php.ini). ولا يمكن تغيير هذا الإعداد إلا في php.ini.
expose_php = Off
هذا مثال لخادم VPS بنظام Ubuntu يستخدم PHP-FPM (غيّر 8.3 بحسب إصدار PHP لديك).
# تحقق من الإعداد الحالي
grep -n '^expose_php' /etc/php/8.3/fpm/php.ini
# بعد التعديل أعد تشغيل PHP-FPM
sudo systemctl restart php8.3-fpm
في حزمة php.ini لنظام Ubuntu يكون expose_php = Off افتراضيًا. فإذا ظهرت الترويسة فتحقق من أن ملف php.ini آخر لا يُستخدم. وفي الاستضافات المؤجَّرة قد يمكن التغيير من إعدادات PHP في لوحة الإدارة وقد لا يمكن.
وإذا تعذّر عليك تغيير php.ini فيمكن إزالة الترويسة من شيفرة WordPress. لكن send_headers خطاف يعمل عندما يعرض WordPress صفحات الواجهة الأمامية، فلا يؤثر في لوحة التحكم وصفحة تسجيل الدخول.
add_action( 'send_headers', function () {
header_remove( 'X-Powered-By' );
} );
الخطوة 5: رفض الوصول إلى readme.html وlicense.txt
الملفان readme.html وlicense.txt من ملفات نواة WordPress. لا يتضمن readme.html الحالي رقم إصدار، لكنه يدل على أنك تستخدم WordPress.
وإذا حذفتهما فسيعودان عند تحديث نواة WordPress. ورفض الوصول من خادم الويب أقل جهدًا من الحذف.
في حالة Apache (.htaccess)
أضف إلى .htaccess في مجلد WordPress. ما بين # BEGIN WordPress و# END WordPress يعيد WordPress كتابته، فاكتب خارج هذا النطاق. هذه صيغة Apache 2.4 (Order وDeny from all صيغة قديمة من Apache 2.2).
<FilesMatch "^(readme\.html|license\.txt)$">
Require all denied
</FilesMatch>
في حالة Nginx
أضف إلى كتلة server الخاصة بموقعك، وتحقق من الإعداد ثم أعد التحميل.
location ~* ^/(readme\.html|license\.txt)$ {
deny all;
}
sudo nginx -t && sudo systemctl reload nginx
بعد الإضافة نفّذ curl -s -o /dev/null -w '%{http_code}\n' https://example.com/readme.html وتأكد من إعادة 403.
ما لا يمنعه الإخفاء
- محتوى ملفات CSS وJS في WordPress يختلف قليلًا بين إصدار وآخر، فيمكن تخمين الإصدار بجلب الملفات ومقارنتها
- قد يُعرف إصدار الإضافة أو القالب من
readme.txtأوver=فيهما. والأكثر استهدافًا هو ثغرات الإضافات لا النواة - أما من يستطيع تسجيل الدخول إلى لوحة التحكم فيظهر له الإصدار كما هو
لذلك، إلى جانب إخفاء الإصدار، حدّث النواة والإضافات والقوالب، واحذف الإضافات غير المستخدمة، وعطّل تحرير الملفات في لوحة التحكم.
الخلاصة
- يظهر الإصدار أساسًا في generator داخل HTML والخلاصات، وفي
?ver=بروابط CSS وJS. ولا يتضمن/wp-json/في REST API إصدار WordPress - يزيل
add_filter( 'the_generator', '__return_empty_string' );generator في HTML والخلاصات معًا - لا تحذف
?ver=بل استبدل القيمة المطابقة لإصدار WordPress وحدها، فلا يتوقف تحديث الكاش - أوقف
X-Powered-Byبـexpose_php = Offفي php.ini - يعود
readme.htmlبعد التحديث حتى لو حذفته، فارفض الوصول إليه من خادم الويب - الإخفاء إجراء مساعد، والأهم هو مواصلة التحديث
مقالات ذات صلة:
- إعداد ترويسات الأمان في WordPress | .htaccess وNginx وfunctions.php
- كيفية تقييد الوصول إلى REST API في WordPress
- تعطيل محرر ملفات القوالب والإضافات في WordPress | DISALLOW_FILE_EDIT
لديك أسئلة حول WordPress؟ ناشر هذا الموقع موجود في اليابان ويرد باللغة اليابانية. تواصل معنا (باليابانية)