The WordPress Meta “generator” Tag Paranoia

WordPress Version

…or “WordPress Version Fingerprinting”

I have read dozens of “How to secure your WordPress” articles, and one common “tip” among others is getting rid of the “generator” tag in the HTML head, for additional security through obscurity.

WordPress uses the meta “generator” tag to “disclose” its version. The paranoia surrounding this fact is unbelievable, and they think that by removing it they harden WordPress. And that is absolutely not true.

Here’s why: See that? That works on all WordPress sites. The readme.html is shipped with every version of WordPress since at least 1.5. Will they be scared now? None of the tutorials on how to remove the “generator” tag ever mention this file. There’s no point in “patching” one hole without “patching” another, is there? Water will still come through.

Okay, let’s delete or rename the readme.html file. That won’t help either. With a little bit more work we can still find out what WordPress version is running. How?

Fingerprinting WordPress

WordPress is constantly evolving with new features and fixes. Changes are made to static files as well, so by scanning those we can generate fingerprints (calling them “signatures” works equally well) and then compare them.

The starting point would be the WordPress source code, which we’ll parse and compile a list of fingerprints in iterations. Here’s how the first iteration would look:

WordPress 1.5

Has a wp-admin.css file. Contents would be hashed, potential targets would be scanned for this file.

WordPress 2.0

JavaScript is introduced. A /wp-includes/js/ folder now exists that will contain all the files that are necessary for generating and comparing fingerprints/signatures. The db-key.js is one file that introduced in this version.

WordPress 2.1

autosave-js.php is introduced.

WordPress 2.2

autosave-js.php is moved to autosave.js. jQuery introduced.

WordPress 2.3

prototype.js has changed in relation to previous version.

WordPress 2.5

list-manipulation.js is gone. autosave.js has been changed. Would be hashed and checked against.

WordPress 2.6

wp-ajax.js is gone. autosave.js has new changes again, a new fingerprint.

WordPress 2.7

comment-reply.js has been introduced among a couple of other files and changes.

WordPress 2.8

Minification is introduced. swobject.js is present in this version.

WordPress 2.9

autosave.js has its unique share of content, meaning a unique hash. json2.js is introduced.

WordPress 3.0

autosave.js is different again. codepress with all its files is gone.

WordPress 3.1

admin-bar.js is introduced.

WordPress 3.2

autosave.js is now of different size an content.

WordPress 3.3

Plupload is introduced, meaning plupload.js is available.

This is only the beginning, these are example files that change. Combinations of files and changes would be built into complex fingerprints or signatures and a site would be scanned against them version by version, excluding versions as it goes. For example:

  • does plupload.js exist?
  • WordPress 3.3 gets -= 1 point
  • is autosave.js md5 hash ….?
  • WordPress 3.2 gets += 1 point

The version with most points would then be selected, runners up could be displayed in case some versions overlap or you decide to fingerprint minor WordPress versions as well. Fingerprint patterns can be weighted for additional accuracy. Simple. Will take a little more work than writing a parser for index.html or the “generator” tag, but works and can seldom be fooled. Think of added images, the wp-admin directory has also got a js directory with static files, maybe themes.

Further reading


So, don’t remove the “generator” tag. They’ll find out what version you’re running regardless. Leave it there, and place the $wp_version global in the footer of your site, as a reminder to keep it up-to-date at all times and keep you on your toes at all times. Subscribe to the WordPress releases archive to be in the know.

Stay safe.