2026年11月12日

2026年11月12日

WordPress का वर्शन छिपाने का तरीका: generator टैग, ver= और readme.html

यह लेख जापानी मूल लेख का स्थानीयकृत संस्करण है। जापानी मूल लेख पढ़ें

WordPress शुरुआती स्थिति में पेज के HTML और फ़ीड में अपना वर्शन नंबर लिख देता है। हमलावर इसे देखकर पता लगाते हैं कि कहीं यह ऐसा वर्शन तो नहीं जिसमें कोई ज्ञात कमज़ोरी हो। इस लेख में बताया गया है कि वर्शन कहाँ-कहाँ दिखता है और उसे कैसे छिपाएँ। जानकारी अक्टूबर 2026 तक की है।

सबसे पहले यह जान लें कि वर्शन छिपाना एक सहायक उपाय है। CSS और JavaScript फ़ाइलों की सामग्री आदि से भी वर्शन का अंदाज़ा लगाया जा सकता है, इसलिए छिपाने से पहचान रुक जाए, ऐसा ज़रूरी नहीं। सबसे ज़्यादा असर इससे होता है कि WordPress कोर, प्लगइन और थीम को ताज़ा रखा जाए।

वर्शन कहाँ दिखता है

जगह क्या दिखता है उपाय
HTML का <head> <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 के URL style.min.css?ver=6.9.4 जैसा ?ver= style_loader_src और script_loader_src फ़िल्टर
HTTP हेडर X-Powered-By: PHP/8.3.x (WordPress का नहीं, PHP का वर्शन) php.ini का expose_php
readme.html यह कि WordPress इस्तेमाल हो रहा है (मौजूदा readme.html में वर्शन नंबर नहीं लिखा होता) पहुँच रोकना

REST API का /wp-json/ जो साइट जानकारी लौटाता है (नाम, विवरण, URL, टाइमज़ोन, नेमस्पेस आदि), उसमें WordPress का वर्शन शामिल नहीं होता। वर्शन छिपाने के लिए REST API का आउटपुट काटने की ज़रूरत नहीं है।

चरण 1: अभी की दिखावट जाँचें

अपनी साइट के URL से बदलकर, अपने कंप्यूटर या सर्वर पर चलाएँ। कैश प्लगइन या CDN इस्तेमाल करते हों तो बदलाव के बाद कैश हटाकर ही जाँचें।

# HTML का generator टैग
curl -s https://example.com/ | grep -i 'name="generator"'

# फ़ीड का generator
curl -s https://example.com/feed/ | grep -i '<generator>'

# CSS-JS में लगे ver= के मानों की सूची
curl -s https://example.com/ | grep -oE 'ver=[0-9][0-9.]*' | sort | uniq -c

# HTTP हेडर का X-Powered-By
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= की सूची में वही मान है जो एडमिन स्क्रीन के “डैशबोर्ड” (Dashboard) → “अपडेट” (Updates) में WordPress के वर्शन के रूप में दिखता है, तो उस CSS या JS से WordPress का वर्शन पता चल जाता है। WordPress कोर या थीम CSS-JS लोड करते समय वर्शन न दें, तो WordPress का वर्शन ver= में आ जाता है।

चरण 2: कोड रखने की जगह तय करें

इस लेख का कोड इन दोनों में से किसी एक जगह रखें।

  • mu-plugin (अनुशंसित): wp-content/mu-plugins/ फ़ोल्डर में (न हो तो बनाएँ) PHP फ़ाइल रखने पर वह बिना सक्रिय किए लोड होती है। थीम बदलने पर भी असर बना रहता है
  • चाइल्ड थीम का 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 टैग और CSS-JS के ver= में दिखने वाला WordPress का वर्शन छिपाता है।
 */

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

// HTML के <meta name="generator"> और फ़ीड के <generator> को ख़ाली कर देता है।
add_filter( 'the_generator', '__return_empty_string' );

/**
 * CSS-JS का ver= सिर्फ़ तब दूसरे मान से बदलता है जब वह 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 फ़िल्टर HTML के generator टैग और फ़ीड के generator, दोनों पर असर करता है। remove_action( 'wp_head', 'wp_generator' ); सिर्फ़ HTML का टैग हटाता है, फ़ीड पर असर नहीं करता
  • ?ver= सब हटा देने पर प्लगइन या थीम अपडेट करने के बाद ब्राउज़र पुरानी CSS-JS ही इस्तेमाल करता रह सकता है। ऊपर का कोड सिर्फ़ तब, जब मान WordPress के वर्शन जैसा हो, उसे वर्शन से बनी दूसरी स्ट्रिंग से बदलता है। WordPress अपडेट होने पर मान भी बदल जाता है, इसलिए कैश ताज़ा हो जाता है
  • प्लगइन या थीम अपना ख़ुद का वर्शन नंबर देकर जो ver= लगाते हैं, उन्हें नहीं बदला जाता

सहेजने के बाद चरण 1 की कमांड से जाँचें कि generator नहीं दिखता और ver= की सूची में WordPress का वर्शन नहीं बचा। कैश प्लगइन इस्तेमाल करते हों तो कैश हटाकर जाँचें।

चरण 4: X-Powered-By हेडर बंद करें

X-Powered-By हेडर WordPress नहीं, PHP लगाता है, और इससे PHP का वर्शन पता चलता है। इसे बंद करने के लिए PHP की सेटिंग फ़ाइल (php.ini) में expose_php को Off करें। यह सेटिंग सिर्फ़ 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

Ubuntu पैकेज की php.ini शुरुआत में ही 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) के लिए

WordPress के फ़ोल्डर की .htaccess में जोड़ें। # 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 लौटता है।

छिपाने पर भी जो नहीं रुकता

  • WordPress की CSS-JS फ़ाइलों की सामग्री हर वर्शन में थोड़ी-थोड़ी अलग होती है, इसलिए फ़ाइल लेकर मिलाने से वर्शन का अंदाज़ा लग सकता है
  • प्लगइन या थीम की readme.txt या ver= से प्लगइन का वर्शन पता चल सकता है। निशाना आम तौर पर कोर से ज़्यादा प्लगइन की कमज़ोरियाँ बनती हैं
  • जो एडमिन स्क्रीन में लॉगिन कर सकता है उसे वर्शन पहले की तरह दिखता रहता है

इसलिए वर्शन छिपाने के साथ कोर, प्लगइन और थीम को अपडेट रखें, इस्तेमाल न होने वाले प्लगइन हटाएँ और एडमिन स्क्रीन में फ़ाइल एडिटिंग बंद करें।

सारांश

  • वर्शन मुख्य रूप से HTML और फ़ीड के generator तथा CSS-JS के ?ver= में दिखता है। REST API के /wp-json/ में WordPress का वर्शन शामिल नहीं होता
  • add_filter( 'the_generator', '__return_empty_string' ); से HTML और फ़ीड दोनों का generator हट जाता है
  • ?ver= को हटाएँ नहीं; सिर्फ़ WordPress के वर्शन जैसे मान को बदलें, तो कैश का अपडेट भी नहीं रुकता
  • X-Powered-By को php.ini के expose_php = Off से बंद करें
  • readme.html हटाने पर अपडेट में लौट आती है, इसलिए वेब सर्वर पर पहुँच रोकें
  • छिपाना एक सहायक उपाय है, सबसे ज़रूरी बात है अपडेट जारी रखना

संबंधित लेख:

WordPress के बारे में सवाल हैं? इस साइट के प्रकाशक जापान में हैं और जापानी में जवाब देते हैं। संपर्क (जापानी)

お気軽にご相談ください

お見積りへ お問い合わせへ
▲