WordPress includes its version number in several places in the page output by default: a <meta name="generator"> tag in the <head>, a generator element in RSS and Atom feeds, and a ?ver= query string appended to many core CSS and JavaScript files. While none of these represent a vulnerability on their own, they do provide automated vulnerability scanners with a straightforward way to identify your WordPress version, and from there, look up which known exploits apply to it.
Removing the version number doesn’t make your site secure in isolation, but it raises the cost of targeted automated attacks. Combined with keeping WordPress updated, it reduces the window of exposure even if attackers know a new vulnerability has been disclosed.
The Code
Add this to your functions.php or a site-specific plugin. It addresses version exposure across all three locations where WordPress outputs it by default.
What Each Part Does
remove_action( 'wp_head', 'wp_generator' ) unhooks the function responsible for printing the <meta name="generator" content="WordPress X.X.X"> tag in the HTML head. This is the most visible exposure point and the one automated scanners check first.
The the_generator filter set to __return_empty_string removes the generator tag from RSS and Atom feeds. WordPress outputs this in a slightly different format in feeds, for example, <?xml ... ?><generator>https://wordpress.org/?v=X.X.X</generator>, so the head removal alone doesn’t cover it. This filter handles feeds specifically.
The nsl_strip_wp_version_from_src function targets query strings specifically. WordPress appends ?ver=X.X.X to its own core CSS and JavaScript files, things like wp-includes/js/jquery/jquery.min.js?ver=3.7.1. The function checks whether the ver query argument matches the current WordPress version, and if so, removes it. It only strips the WordPress version, not custom version strings added by themes and plugins, which preserves cache-busting behaviour for your own assets.
What This Doesn’t Cover
Version number hiding is a surface-level hardening measure, not a comprehensive security solution. Determined scanners have other ways to fingerprint WordPress versions, through file hashes, the contents of readme.html (which you should also delete from the server), and patterns in HTML comments left by themes. The most important protection remains keeping WordPress, themes, and plugins updated promptly when security releases are issued.
Combining With Other Security Snippets
This snippet pairs naturally with disabling XML-RPC, hiding file editing in the admin, and adding security headers, all of which reduce the attack surface of a standard WordPress installation without affecting front-end functionality. Consider applying all of them together as a baseline hardening pass on any new WordPress site before launch.
// Remove version from <head>
remove_action( 'wp_head', 'wp_generator' );
// Remove version from RSS and Atom feeds
add_filter( 'the_generator', '__return_empty_string' );
// Remove WordPress version from script and style query strings
add_filter( 'style_loader_src', 'nsl_strip_wp_version_from_src', 9999 );
add_filter( 'script_loader_src', 'nsl_strip_wp_version_from_src', 9999 );
function nsl_strip_wp_version_from_src( $src ) {
global $wp_version;
if ( strpos( $src, 'ver=' . $wp_version ) !== false ) {
$src = remove_query_arg( 'ver', $src );
}
return $src;
}
