The fix, in one snippet
remove_action('wp_head', 'wp_generator');
rm /var/www/html/readme.html
Illustrative values. Change the paths, hostnames and options to match your own site before using it.
The sections below explain what is tested, why it matters and the alternatives.
What we test
This check runs only when WordPress is detected (paths under /wp-content/ or /wp-includes/, or a WordPress generator tag). Scan.now then looks for the version in four places: the <meta name="generator" content="WordPress 6.x.y"> tag; ?ver=6.x.y query strings on scripts and styles served from /wp-includes/; /readme.html, which states "Version 6.x" in its heading; and the <generator> element of /feed/. Any of them failing yields a low-severity finding naming the source and the version. When the version is behind the current WordPress release known to the scanner, the report says so, which raises the practical priority. Plugin and theme versions are not enumerated. The general CMS case is generator-disclosure; the WordPress-specific endpoints xmlrpc.php and user enumeration have their own checks.
Why it matters
WordPress powers a large share of the web, and the bots that attack it are tuned accordingly: read the version, pick the matching exploit, move on. Core has a good security record and minor releases auto-update by default, so an accurate current version reveals little, but a site showing an old version is announcing that auto-updates are off or broken, which usually means plugins are stale too, and plugins are where most WordPress compromises start. Hiding the version does not patch anything and a determined attacker can date a site from file hashes, so this is rated low. The value in fixing it is that it takes five minutes and removes the site from the cheapest tier of automated targeting. The WordPress scanning guide explains what else an external scan reveals and the order in which to harden.
How to fix it
Strip the version from the generator tag, feeds and asset URLs with a small must-use plugin or in the theme's functions.php:
remove_action('wp_head', 'wp_generator');
add_filter('the_generator', '__return_empty_string');
function scan_strip_ver($src) {
return $src ? remove_query_arg('ver', $src) : $src;
}
add_filter('style_loader_src', 'scan_strip_ver', 9999);
add_filter('script_loader_src', 'scan_strip_ver', 9999);
Block readme.html (core updates recreate it, so block rather than delete). nginx:
location = /readme.html { return 404; }
location = /license.txt { return 404; }
Apache:
<FilesMatch "^(readme\.html|license\.txt)$">
Require all denied
</FilesMatch>
Then make the version irrelevant: confirm automatic background updates are on (define('WP_AUTO_UPDATE_CORE', true); in wp-config.php enables major releases as well as minor), enable auto-updates for plugins and themes from the Plugins screen, and remove anything unused. Cloudflare's WordPress managed WAF ruleset adds a layer against known exploits while you catch up.
Where this fits
WordPress version disclosure is check 11 of 14 that the website vulnerability scanner runs under exposed files and information disclosure, ordered the way they are worth fixing. That ordering is the point: Fixing this one while the check above it still fails buys less than it looks like.
Fix this one first
Above it in the same category sits HTTP TRACE method enabled (low), where the server answers HTTP TRACE requests by echoing them back. An attacker who has that does not need this, so it is the better use of the same hour.
What fixing this still leaves open
WordPress version disclosure closes one route in. Immediately below it: Redirect parameters on the page, where links or forms on the page carry parameters whose names and values suggest a redirect target (next=, return_to=, url=); robots.txt review, where a review of robots.txt; security.txt (RFC 9116) present, where no security.txt file was found at /.well-known/security.txt, or the one present is invalid or expired.
Found in the same scan
The website vulnerability scanner reports this alongside checks from other categories that are at least as serious, including Certificate chain and hostname validation, where the certificate presented for this hostname did not validate: The chain does not reach a trusted root, an intermediate is missing, the name does not match, or the certificate is self-signed or expired, and HTTPS is available, where the site could not be reached over HTTPS on port 443, or the TLS handshake failed. A single run of website vulnerability scanner answers all of them at once.
The first few lines
You are a senior web engineer. I ran a security and SEO scanner against my site and it reported the finding below. Fix it properly rather than suppressing the symptom.
Finding: WordPress version disclosure (low severity)
Scanner check id: wordpress-version-disclosure
The rest of this prompt names the pages and line numbers we found the problem on, the configuration to change, and the constraints a good answer has to respect. It is free, it just needs an account so the work is not scraped wholesale.
Sign in with GoogleSigning in is free and takes one click. We store your email address and nothing else.