This article examines how and why version numbers for the WordPress core, plugins, and themes are exposed to public in your WordPress website with its default configuration, details the associated security implications, and provides methods to harden your WordPress website security by removing or hiding this information.
Why Your WordPress Site Leaks Version Numbers
Cache-busting: By default WordPress uses an insecure mechanism for handling the cache-busting on static CSS and JS files – at the end of each file path it adds a “?ver” query string parameter which contains the version number of either a WordPress core, theme, plugin or a specific javascript library. Such method ensures that the website will not return outdated versions of the static files from the browser or CDN cache.
/wp-content/plugins/woocommerce/assets/client/blocks/wc-blocks.css?ver=wc-10.1.1
/wp-content/plugins/contact-form-7/includes/css/styles.css?ver=6.1.1
/wp-content/themes/twentytwentyfive/style.css?ver=1.3
/plugins/sitepress-multilingual-cms/res/js/cookies/language-cookie.js?ver=476000
/wp-content/plugins/woocommerce-multilingual/res/js/cart_widget.min.js?ver=5.5.1
/wp-includes/blocks/navigation/style.min.css?ver=6.8.2
Marketing & Statistics: Other common ways on how WordPress and some certain plugins advertises their version numbers is through meta “generator” tags or HTML comments added in the site HTML code. This however does not benefit the website in any way and is done purely for marketing and statistics purposes.
<meta name=”generator” content=”WordPress 6.8.2″ />
<meta name=”generator” content=”WooCommerce 10.1.1″ />
<meta name=”generator” content=”Redux 4.5.7″ />
<meta name=”generator” content=”WPML ver:4.7.6 stt:1,3;” />
<meta name=”generator” content=”Elementor 3.31.2; features: e_font_icon_svg, additional_custom_breakpoints, e_element_cache; settings: css_print_method-external, google_font-enabled, font_display-swap”>
<!– This site is optimized with the Yoast SEO plugin v25.7 – https://yoast.com/wordpress/plugins/seo/ –>
How to harden website security by removing or obfuscating this information
Each of the solutions you see further below, you can apply to your Website by pasting the code into your theme functions file or a must-use plugin.
Use custom version numbers for static resources
For this you will first have to add an extra constant to your WordPress configuration file (wp-config.php). This will define your site’s version, which you will have to manually update each time when updating WordPress core, plugins or themes.
define('SITE_VERSION', '1.00');
To preserve the cache busting this script will REPLACE all version numbers in the file paths with the one you provided, instead of just removing them.
<?php
//Replace the version numbers (?ver=XXX) in the file paths of static JS/CSS files
function dwp_custom_versioning_for_css_js_files( $src ) {
$ver = defined('SITE_VERSION') ? SITE_VERSION : date('Ymd');
if(strpos($src,'?ver=')) $src = add_query_arg('ver', $ver, remove_query_arg( 'ver', $src ));
return $src;
}
add_filter( 'style_loader_src', 'dwp_custom_versioning_for_css_js_files', 9999 );
add_filter( 'script_loader_src', 'dwp_custom_versioning_for_css_js_files', 9999 );
Remove the meta “generator” tags
<?php
//Remove the META generator tags from the WordPress website
function dwp_remove_generator_meta_tags($output) {
$output = preg_replace('/<meta[^>]*name=[\'"]generator[\'"][^>]*>/i', '', $output);
return $output;
}
add_action('wp_head', function() {
ob_start('dwp_remove_generator_meta_tags');
}, 1);
add_action('wp_head', function() {
ob_end_flush();
}, 999);
//Remove the META generator tag from WordPress RSS feeds
add_action('init', function() {
add_filter('the_generator', '__return_empty_string');
});
Remove HTML comments which expose the version information
You can completely remove the HTML comments from your sites code with a script aggregating and code delivery optimization plugins like Autoptimize, however if want to remove only version leaking HTML comments from your site’s code there is no universal solution to apply as each of such HTML comment can be constructed differently. In that case you need to apply plugin or theme specific filters for each case.
For example you can use this filter to remove the Yoast SEO markers from the site code:
add_filter('wpseo_debug_markers', '__return_false');
How exposed version numbers becomes a security problem
WordPress as an open-source platform has a long history with publicly available plugins and themes containing security flaws or vulnerabilities in their specific versions. While the quality of WordPress core is strictly controlled, this cannot be said about WordPress plugins and themes made by independent developers or companies. With each WordPress plugin or theme you install, you basically trust its author as there is no guarantee on quality of the product, even if its highly popular and downloaded from the official WordPress repository. From time to time developers make mistakes and leave a security holes behind in their work. Once a specific version of the product is released publicly, someone will download and install it. If it contains a vulnerability, it can only be fixed with a release of the next version of the product – then its up to Website owners if they manage to download the update in time, however most of the WordPress websites do not get updated on a regular basis.
Why it is dangerous to keep version numbers exposed
Publicly available WordPress websites are being probed and scanned on a daily basis by tons of a automated robot-like software units which are made just for one intention – to find a vulnerability on your site and to take control over it. Just one website can receive thousands of requests per day from such malicious bots.
The time and resources costs money – even for hackers. While it is possible to just blindly scan your site against tens of thousands different vulnerabilities, it is expensive, especially if the robot needs to scan thousands of websites per day, and here’s why:
- Most of the WordPress websites are slow because of poor configuration. An average response time of a single request could take around 0.5 seconds.
- Website hosting could have additional protections, such as “Rate Limiting” or “Web Application Firewall” which can limit or block the malicious bots from scanning the website.
Therefore leaving exposed version numbers on your WordPress website provides an opportunity for hackers to do more targeted vulnerability scans. As many of the themes and plugins output their scripts and styles in the site code, it makes possible to quickly gather information about what kind of plugins and themes you’re using on your WordPress website bu just querying its home page.